geojson#FeatureCollection TypeScript Examples

The following examples show how to use geojson#FeatureCollection. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: map-utils.service.ts    From geonetwork-ui with GNU General Public License v2.0 7 votes vote down vote up
getGFIFeaturesObservablesFromClick(
    olMap,
    event
  ): Observable<OlFeature<Geometry>[]>[] {
    const wmsLayers = olMap.getLayers().getArray().filter(this.isWMSLayer)

    if (wmsLayers.length > 0) {
      const { coordinate } = event
      const gfiUrls = wmsLayers.reduce(
        (urls, layer) => [...urls, this.getGFIUrl(layer, olMap, coordinate)],

        []
      )
      return gfiUrls.map((url) =>
        this.http
          .get<FeatureCollection>(url)
          .pipe(map((collection) => this.readFeatureCollection(collection)))
      )
    } else {
      return []
    }
  }
Example #2
Source File: map-utils.service.ts    From geonetwork-ui with GNU General Public License v2.0 7 votes vote down vote up
readFeatureCollection = (
    featureCollection: FeatureCollection,
    featureProjection = FEATURE_PROJECTION,
    dataProjection = DATA_PROJECTION
  ): OlFeature<Geometry>[] => {
    const olFeatures = new GeoJSON().readFeatures(featureCollection, {
      featureProjection,
      dataProjection,
    })
    return olFeatures
  }
Example #3
Source File: ews-utils.ts    From prism-frontend with MIT License 7 votes vote down vote up
fetchEWSLocations = async (
  baseUrl: string,
): Promise<FeatureCollection> => {
  const url = `${baseUrl}/location.geojson?type=River`;

  const resp = await fetch(url);
  const featureCollection: FeatureCollection = await resp.json();

  return featureCollection;
}
Example #4
Source File: analysis-utils.ts    From prism-frontend with MIT License 7 votes vote down vote up
constructor(
    tableData: TableRow[],
    tableColumns: Column[],
    featureCollection: FeatureCollection,
    hazardLayer: WMSLayerProps,
    adminLevel: AdminLevelType,
    statistic: 'area' | 'percentage',
    threshold?: ThresholdDefinition,
  ) {
    this.featureCollection = featureCollection;
    this.tableData = tableData;
    this.tableColumns = tableColumns;
    this.statistic = statistic;
    this.threshold = threshold;
    this.adminLevel = adminLevel;

    // color breaks from https://colorbrewer2.org/#type=sequential&scheme=Reds&n=5
    // this legend of red-like colors goes from very light to dark
    this.legend = [
      { label: '20%', value: 0.2, color: '#fee5d9' }, // very light red-orange, HSL: 0.05, 0.95, 0.92,
      { label: '40%', value: 0.4, color: '#fcae91' }, // rose bud, HSL: 0.05, 0.95, 0.78,
      { label: '60%', value: 0.6, color: '#fb6a4a' }, // red-orange, HSL: 0.03, 0.96, 0.64
      { label: '80%', value: 0.8, color: '#de2d26' }, // medium red-orange HSL: 0.01, 0.74, 0.51
      { label: '100%', value: 1, color: '#a50f15' }, // dark tamarillo red: 0.99 0.83 0.35, dark red
    ];

    this.legendText = hazardLayer.legendText;
    this.hazardLayerId = hazardLayer.id;
  }
Example #5
Source File: analysis-utils.ts    From prism-frontend with MIT License 7 votes vote down vote up
constructor(
    tableData: TableRow[],
    featureCollection: FeatureCollection,
    hazardLayer: WMSLayerProps,
    baselineLayer: AdminLevelDataLayerProps,
    statistic: AggregationOperations,
    threshold: ThresholdDefinition,
    rawApiData?: object[],
  ) {
    this.featureCollection = featureCollection;
    this.tableData = tableData;
    this.statistic = statistic;
    this.threshold = threshold;
    this.legend = baselineLayer.legend;
    this.legendText = hazardLayer.legendText;
    this.rawApiData = rawApiData;

    this.hazardLayerId = hazardLayer.id;
    this.baselineLayerId = baselineLayer.id;
  }
Example #6
Source File: analysis-utils.ts    From prism-frontend with MIT License 7 votes vote down vote up
constructor(
    featureCollection: FeatureCollection,
    statistic: AggregationOperations,
    legend: LegendDefinition,
    legendText: string,
    groupBy: string,
    key: string,
  ) {
    this.featureCollection = featureCollection;
    this.statistic = statistic;
    this.legend = legend;
    this.legendText = legendText;
    this.groupBy = groupBy;
    this.key = key;
  }
Example #7
Source File: analysis-utils.ts    From prism-frontend with MIT License 6 votes vote down vote up
featureCollection: FeatureCollection;
Example #8
Source File: data.service.ts    From geonetwork-ui with GNU General Public License v2.0 6 votes vote down vote up
readDataset(
    url: string,
    typeHint?: SupportedType
  ): Observable<FeatureCollection> {
    const proxiedUrl = this.proxy.getProxiedUrl(url)
    return from(readDataset(proxiedUrl, typeHint)).pipe(
      catchError((error) => {
        if (error.isCrossOriginOrNetworkRelated) {
          return throwError(new Error('dataset.error.network'))
        } else if (error.httpStatus) {
          return throwError(new Error('dataset.error.http'))
        } else if (error.parsingFailed) {
          return throwError(new Error('dataset.error.parse'))
        } else {
          return throwError(new Error('dataset.error.unknown'))
        }
      }),
      map((features) => ({
        type: 'FeatureCollection',
        features,
      }))
    )
  }
Example #9
Source File: sofar-availability.ts    From aqualink-app with MIT License 6 votes vote down vote up
export function getSofarWaveModelAvailability(): FeatureCollection<Point> {
  if (!geojson) {
    geojson = {
      type: 'FeatureCollection',
      features: availabilityPoints.map((coordinate) => ({
        type: 'Feature',
        geometry: {
          type: 'Point',
          coordinates: coordinate,
        },
      })),
    };
  }
  return geojson;
}
Example #10
Source File: analysis-utils.ts    From prism-frontend with MIT License 6 votes vote down vote up
featureCollection: FeatureCollection;
Example #11
Source File: analysis-utils.ts    From prism-frontend with MIT License 6 votes vote down vote up
featureCollection: FeatureCollection;
Example #12
Source File: UsePathDetailsLayer.tsx    From graphhopper-maps with Apache License 2.0 6 votes vote down vote up
function createHighlightedPathSegments(segments: Coordinate[][]) {
    const featureCollection: FeatureCollection = {
        type: 'FeatureCollection',
        features: [
            {
                type: 'Feature',
                geometry: {
                    type: 'MultiLineString',
                    coordinates: segments.map(s => s.map(c => fromLonLat([c.lng, c.lat]))),
                },
                properties: {},
            },
        ],
    }
    return featureCollection
}
Example #13
Source File: UsePathsLayer.tsx    From graphhopper-maps with Apache License 2.0 6 votes vote down vote up
function createUnselectedPaths(paths: Path[]) {
    const featureCollection: FeatureCollection = {
        type: 'FeatureCollection',
        features: paths.map((path, index) => {
            return {
                type: 'Feature',
                properties: {
                    index,
                },
                geometry: {
                    ...path.points,
                    coordinates: path.points.coordinates.map(c => fromLonLat(c)),
                },
            }
        }),
    }
    return featureCollection
}
Example #14
Source File: leaflet-textpath-tests.ts    From Teyvat.moe with GNU General Public License v3.0 6 votes vote down vote up
flightsEW: FeatureCollection = {
    type: 'FeatureCollection',
    features: [
        {
            type: 'Feature',
            properties: {
                flight: 'To Bangkok',
            },
            geometry: {
                type: 'LineString',
                coordinates: [
                    [106.67724609375, 10.790140750321738],
                    [104.08447265624999, 11.523087506868514],
                    [102.1728515625, 12.254127737657381],
                    [100.45898437499999, 13.667338259654947],
                ],
            },
        },
    ],
}
Example #15
Source File: leaflet-textpath-tests.ts    From Teyvat.moe with GNU General Public License v3.0 6 votes vote down vote up
flightsWE: FeatureCollection = {
    type: 'FeatureCollection',
    features: [
        {
            type: 'Feature',
            properties: {
                flight: 'To New Delhi',
            },
            geometry: {
                type: 'LineString',
                coordinates: [
                    [3.33984375, 46.6795944656402],
                    [29.53125, 46.55886030311719],
                    [51.328125, 42.293564192170095],
                    [68.5546875, 35.746512259918504],
                    [76.81640625, 28.65203063036226],
                ],
            },
        },
        {
            type: 'Feature',
            properties: {
                flight: 'To Hanoi',
            },
            geometry: {
                type: 'LineString',
                coordinates: [
                    [77.607421875, 28.767659105691255],
                    [88.72558593749999, 27.839076094777816],
                    [97.3828125, 25.681137335685307],
                    [105.77636718749999, 21.248422235627014],
                ],
            },
        },
    ],
}
Example #16
Source File: mapSelectors.ts    From react-tutorials with MIT License 6 votes vote down vote up
getMapDataFromFile = () =>
  new Promise((resolve) =>
    fetch('/data/world-110m.json').then((response) => {
      if (response.status !== 200) {
        // eslint-disable-next-line no-console
        console.log(`Houston, we have a problem! ${response.status}`)
        return
      }
      response.json().then((worldData) => {
        const mapFeatures: Array<Feature<Geometry | null>> = ((feature(worldData, worldData.objects.countries) as unknown) as FeatureCollection).features
        resolve(setMapObject(mapFeatures))
      })
    })
  )
Example #17
Source File: WorldMapAtlas.tsx    From react-tutorials with MIT License 6 votes vote down vote up
WorldMapAtlas = () => {
  const [geographies, setGeographies] = useState<[] | Array<Feature<Geometry | null>>>([])

  useEffect(() => {
    fetch('/data/world-110m.json').then((response) => {
      if (response.status !== 200) {
        // eslint-disable-next-line no-console
        console.log(`Houston we have a problem: ${response.status}`)
        return
      }
      response.json().then((worldData) => {
        const mapFeatures: Array<Feature<Geometry | null>> = ((feature(worldData, worldData.objects.countries) as unknown) as FeatureCollection).features
        setGeographies(mapFeatures)
      })
    })
  }, [])

  const projection = geoEqualEarth().scale(scale).translate([cx, cy]).rotate([0, 0])

  return (
    <>
      <svg width={scale * 3} height={scale * 3} viewBox="0 0 800 450">
        <g>
          {(geographies as []).map((d, i) => (
            <path
              key={`path-${uuid()}`}
              d={geoPath().projection(projection)(d) as string}
              fill={`rgba(38,50,56,${(1 / (geographies ? geographies.length : 0)) * i})`}
              stroke="aliceblue"
              strokeWidth={0.5}
            />
          ))}
        </g>
      </svg>
    </>
  )
}
Example #18
Source File: UsePathsLayer.tsx    From graphhopper-maps with Apache License 2.0 6 votes vote down vote up
function createSelectedPath(path: Path) {
    const featureCollection: FeatureCollection = {
        type: 'FeatureCollection',
        features: [
            {
                type: 'Feature',
                properties: {},
                geometry: {
                    ...path.points,
                    coordinates: path.points.coordinates.map(c => fromLonLat(c)),
                },
            },
        ],
    }
    return featureCollection
}
Example #19
Source File: photo.page.ts    From ionic-pwa-example-moment with MIT License 6 votes vote down vote up
readonly address$ = combineLatest([
    this.geolocationPosition$,
    this.languagesService.language$,
  ]).pipe(
    switchMap(([position, language]) =>
      this.httpClient.get<FeatureCollection>(
        `https://nominatim.openstreetmap.org/reverse?lat=${position.latitude}&lon=${position.longitude}&format=geojson&accept-language=${language}`
      )
    ),
    map(json => {
      if (json.features.length === 0) return undefined;
      const properties = json.features[0].properties;
      if (!properties) return undefined;
      return properties['display_name'] as string | undefined;
    }),
    shareReplay({ bufferSize: 1, refCount: true })
  );
Example #20
Source File: App.tsx    From react-tutorials with MIT License 6 votes vote down vote up
function App() {
  const [mapData, setMapData] = useState<Types.MapObject>({ mapFeatures: [] })
  const [coordinatesData, setCoordinatesData] = useState<Types.CoordinatesData[]>([])

  useEffect(() => {
    if (coordinatesData.length === 0) {
      const fileNames = ['./data/world-110m.json', './data/coordinates.csv']
      queue()
        .defer(json, fileNames[0])
        .defer(csv, fileNames[1])
        .await((error, d1, d2: Types.CoordinatesData[]) => {
          if (error) {
            // eslint-disable-next-line no-console
            console.log(`Houston we have a problem:${error}`)
          }
          setMapData({ mapFeatures: ((feature(d1, d1.objects.countries) as unknown) as FeatureCollection).features })
          setCoordinatesData(d2)
        })
    }
  })
  return (
    <div className="App">
      <header className="App-header">
        {/*
          <WorldMapAtlas />
          <RoundWorldMap />
          <RotatingRoundWorldMap />
          <RotatingRoundRotatingRoundWorldMapWithCoordinatesWIthCoordinates />
          <WorldMap mapData={mapData} coordinatesData={coordinatesData} scale={200} cx={400} cy={150} initRotation={50} rotationSpeed={0.5} />
        */}
        <WorldMap mapData={mapData} coordinatesData={coordinatesData} scale={200} cx={400} cy={150} initRotation={50} rotationSpeed={0.5} />
      </header>
    </div>
  )
}
Example #21
Source File: RotatingRoundWorldMap.tsx    From react-tutorials with MIT License 5 votes vote down vote up
WorldMap = () => {
  const [geographies, setGeographies] = useState<[] | Array<Feature<Geometry | null>>>([])
  const [rotation, setRotation] = useState<number>(initRotation)
  const [isRotate, setIsRotate] = useState<Boolean>(false)

  useEffect(() => {
    fetch('/data/world-110m.json').then((response) => {
      if (response.status !== 200) {
        // eslint-disable-next-line no-console
        console.log(`Houston we have a problem: ${response.status}`)
        return
      }
      response.json().then((worldData) => {
        const mapFeatures: Array<Feature<Geometry | null>> = ((feature(worldData, worldData.objects.countries) as unknown) as FeatureCollection).features
        setGeographies(mapFeatures)
      })
    })
  }, [])

  // geoEqualEarth
  // geoOrthographic
  const projection = geoOrthographic().scale(scale).translate([cx, cy]).rotate([rotation, 0])

  AnimationFrame(() => {
    if (isRotate) {
      let newRotation = rotation
      if (rotation >= 360) {
        newRotation = rotation - 360
      }
      setRotation(newRotation + 0.2)
      // console.log(`rotation: ${  rotation}`)
    }
  })

  return (
    <>
      <Button
        size="medium"
        color="primary"
        startIcon={<PlayCircleFilledWhiteIcon />}
        onClick={() => {
          setIsRotate(true)
        }}
      />
      <svg width={scale * 3} height={scale * 3} viewBox="0 0 800 450">
        <g>
          <circle fill="#f2f2f2" cx={cx} cy={cy} r={scale} />
        </g>
        <g>
          {(geographies as []).map((d, i) => (
            <path
              key={`path-${uuid()}`}
              d={geoPath().projection(projection)(d) as string}
              fill={`rgba(38,50,56,${(1 / (geographies ? geographies.length : 0)) * i})`}
              stroke="aliceblue"
              strokeWidth={0.5}
            />
          ))}
        </g>
      </svg>
    </>
  )
}
Example #22
Source File: data.service.ts    From geonetwork-ui with GNU General Public License v2.0 5 votes vote down vote up
readGeoJsonDataset(url: string): Observable<FeatureCollection> {
    return this.readDataset(url, 'geojson')
  }
Example #23
Source File: map-context.service.ts    From geonetwork-ui with GNU General Public License v2.0 5 votes vote down vote up
createLayer(layerModel: MapContextLayerModel): Layer {
    const { type } = layerModel
    const style = this.styleService.styles.default
    switch (type) {
      case MapContextLayerTypeEnum.XYZ:
        return new TileLayer({
          source: new XYZ({
            url: 'url' in layerModel ? layerModel.url : undefined,
            urls: 'urls' in layerModel ? layerModel.urls : undefined,
          }),
        })
      case MapContextLayerTypeEnum.WMS:
        return new TileLayer({
          source: new TileWMS({
            url: layerModel.url,
            params: { LAYERS: layerModel.name },
            gutter: 20,
          }),
        })
      case MapContextLayerTypeEnum.WFS:
        return new VectorLayer({
          source: new VectorSource({
            format: new GeoJSON(),
            url: function (extent) {
              return `${
                layerModel.url
              }?service=WFS&version=1.1.0&request=GetFeature&outputFormat=application/json&typename=${
                layerModel.name
              }&srsname=EPSG:3857&bbox=${extent.join(',')},EPSG:3857`
            },
            strategy: bboxStrategy,
          }),
          style,
        })
      case MapContextLayerTypeEnum.GEOJSON: {
        if ('url' in layerModel) {
          return new VectorLayer({
            source: new VectorSource({
              format: new GeoJSON(),
              url: layerModel.url,
            }),
            style,
          })
        } else {
          let geojson = layerModel.data
          if (typeof geojson === 'string') {
            try {
              geojson = JSON.parse(geojson)
            } catch (e) {
              console.warn('A layer could not be created', layerModel, e)
              geojson = { type: 'FeatureCollection', features: [] }
            }
          }
          const features = this.mapUtils.readFeatureCollection(
            geojson as FeatureCollection
          )
          return new VectorLayer({
            source: new VectorSource({
              features,
            }),
            style,
          })
        }
      }
      default:
        throw new Error(`Unrecognized layer type: ${layerModel.type}`)
    }
  }
Example #24
Source File: geo-table-view.component.ts    From geonetwork-ui with GNU General Public License v2.0 5 votes vote down vote up
@Input() data: FeatureCollection = FEATURE_COLLECTION_POINT_FIXTURE_4326
Example #25
Source File: geo-table-view.component.ts    From geonetwork-ui with GNU General Public License v2.0 5 votes vote down vote up
private geojsonToTableData(geojson: FeatureCollection) {
    return geojson.features.map((f) => ({
      id: f.id,
      ...f.properties,
    }))
  }
Example #26
Source File: analysisResultStateSlice.ts    From prism-frontend with MIT License 5 votes vote down vote up
requestAndStoreExposedPopulation = createAsyncThunk<
  AnalysisResult,
  ExposedPopulationDispatchParams,
  CreateAsyncThunkTypes
>('analysisResultState/requestAndStoreExposedPopulation', async params => {
  const { exposure, date, extent, statistic, wfsLayerId } = params;

  const { id, key } = exposure;

  const wfsLayer = LayerDefinitions[wfsLayerId] as WMSLayerProps;
  const populationLayer = LayerDefinitions[id] as WMSLayerProps;

  const wfsParams: WfsRequestParams = {
    url: `${wfsLayer.baseUrl}/ows`,
    layer_name: wfsLayer.serverLayerName,
    time: moment(date).format(DEFAULT_DATE_FORMAT),
    key,
  };

  const apiRequest = createAPIRequestParams(
    populationLayer,
    extent,
    date,
    wfsParams,
  );

  const apiFeatures = (await fetchApiData(
    ANALYSIS_API_URL,
    apiRequest,
  )) as Feature[];

  const { scale, offset } = populationLayer.wcsConfig ?? {
    scale: undefined,
    offset: undefined,
  };

  const features =
    !scale && !offset
      ? apiFeatures
      : apiFeatures.map(f =>
          scaleFeatureStat(f, scale || 1, offset || 0, statistic),
        );

  const collection: FeatureCollection = {
    type: 'FeatureCollection',
    features,
  };

  const groupBy = apiRequest.group_by;
  const legend = createLegendFromFeatureArray(features, statistic);
  const legendText = wfsLayer.title;

  return new ExposedPopulationResult(
    collection,
    statistic,
    legend,
    legendText,
    groupBy,
    key,
  );
})
Example #27
Source File: RoundWorldMap.tsx    From react-tutorials with MIT License 5 votes vote down vote up
RoundWorldMap = () => {
  const [geographies, setGeographies] = useState<[] | Array<Feature<Geometry | null>>>([])
  // eslint-disable-next-line no-unused-vars,@typescript-eslint/no-unused-vars
  const [rotation, setRotation] = useState<number>(initRotation)

  useEffect(() => {
    fetch('/data/world-110m.json').then((response) => {
      if (response.status !== 200) {
        // eslint-disable-next-line no-console
        console.log(`Houston we have a problem: ${response.status}`)
        return
      }
      response.json().then((worldData) => {
        const mapFeatures: Array<Feature<Geometry | null>> = ((feature(worldData, worldData.objects.countries) as unknown) as FeatureCollection).features
        setGeographies(mapFeatures)
      })
    })
  }, [])

  const projection = geoOrthographic().scale(scale).translate([cx, cy]).rotate([rotation, 0])

  return (
    <svg width={scale * 3} height={scale * 3} viewBox="0 0 800 450">
      <g>
        <circle fill="#f2f2f2" cx={cx} cy={cy} r={scale} />
      </g>
      <g>
        {(geographies as []).map((d, i) => (
          <path
            key={`path-${uuid()}`}
            d={geoPath().projection(projection)(d) as string}
            fill={`rgba(38,50,56,${(1 / (geographies ? geographies.length : 0)) * i})`}
            stroke="aliceblue"
            strokeWidth={0.5}
          />
        ))}
      </g>
    </svg>
  )
}
Example #28
Source File: map-context.service.spec.ts    From geonetwork-ui with GNU General Public License v2.0 4 votes vote down vote up
describe('MapContextService', () => {
  let service: MapContextService

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [HttpClientTestingModule],
      providers: [
        {
          provide: MapStyleService,
          useValue: mapStyleServiceMock,
        },
      ],
    })
    service = TestBed.inject(MapContextService)
  })

  it('should be created', () => {
    expect(service).toBeTruthy()
  })

  describe('#createLayer', () => {
    let layerModel, layer
    describe('XYZ', () => {
      beforeEach(() => {
        layerModel = MAP_CTX_LAYER_XYZ_FIXTURE
        layer = service.createLayer(layerModel)
      })
      it('create a tile layer', () => {
        expect(layer).toBeTruthy()
        expect(layer).toBeInstanceOf(TileLayer)
      })
      it('create a XYZ source', () => {
        const source = layer.getSource()
        expect(source).toBeInstanceOf(XYZ)
      })
      it('set correct urls', () => {
        const source = layer.getSource()
        const urls = source.getUrls()
        expect(urls.length).toBe(3)
        expect(urls[0]).toEqual(
          'https://a.tile.openstreetmap.org/{z}/{x}/{y}.png'
        )
      })
    })
    describe('WMS', () => {
      beforeEach(() => {
        layerModel = MAP_CTX_LAYER_WMS_FIXTURE
        layer = service.createLayer(layerModel)
      })
      it('create a tile layer', () => {
        expect(layer).toBeTruthy()
        expect(layer).toBeInstanceOf(TileLayer)
      })
      it('create a TileWMS source', () => {
        const source = layer.getSource()
        expect(source).toBeInstanceOf(TileWMS)
      })
      it('set correct WMS params', () => {
        const source = layer.getSource()
        const params = source.getParams()
        expect(params.LAYERS).toBe(layerModel.name)
      })
      it('set correct url', () => {
        const source = layer.getSource()
        const urls = source.getUrls()
        expect(urls.length).toBe(1)
        expect(urls[0]).toEqual(layerModel.url)
      })
      it('set WMS gutter of 20px', () => {
        const source = layer.getSource()
        const gutter = source.gutter_
        expect(gutter).toBe(20)
      })
    })

    describe('GEOJSON', () => {
      describe('with inline data', () => {
        beforeEach(() => {
          layerModel = MAP_CTX_LAYER_GEOJSON_FIXTURE
          layer = service.createLayer(layerModel)
        })
        it('create a VectorLayer', () => {
          expect(layer).toBeTruthy()
          expect(layer).toBeInstanceOf(VectorLayer)
        })
        it('create a VectorSource source', () => {
          const source = layer.getSource()
          expect(source).toBeInstanceOf(VectorSource)
        })
        it('add features', () => {
          const source = layer.getSource()
          const features = source.getFeatures()
          expect(features.length).toBe(layerModel.data.features.length)
        })
      })
      describe('with inline data as string', () => {
        beforeEach(() => {
          layerModel = { ...MAP_CTX_LAYER_GEOJSON_FIXTURE }
          layerModel.data = JSON.stringify(layerModel.data)
          layer = service.createLayer(layerModel)
        })
        it('create a VectorLayer', () => {
          expect(layer).toBeTruthy()
          expect(layer).toBeInstanceOf(VectorLayer)
        })
        it('create a VectorSource source', () => {
          const source = layer.getSource()
          expect(source).toBeInstanceOf(VectorSource)
        })
        it('add features', () => {
          const source = layer.getSource()
          const features = source.getFeatures()
          expect(features.length).toBe(
            (MAP_CTX_LAYER_GEOJSON_FIXTURE.data as FeatureCollection).features
              .length
          )
        })
      })
      describe('with invalid inline data as string', () => {
        beforeEach(() => {
          const spy = jest.spyOn(global.console, 'warn')
          spy.mockClear()
          layerModel = { ...MAP_CTX_LAYER_GEOJSON_FIXTURE, data: 'blargz' }
          layer = service.createLayer(layerModel)
        })
        it('create a VectorLayer', () => {
          expect(layer).toBeTruthy()
          expect(layer).toBeInstanceOf(VectorLayer)
        })
        it('outputs error in the console', () => {
          expect(global.console.warn).toHaveBeenCalled()
        })
        it('create an empty VectorSource source', () => {
          const source = layer.getSource()
          expect(source).toBeInstanceOf(VectorSource)
          expect(source.getFeatures().length).toBe(0)
        })
      })
      describe('with remote file url', () => {
        beforeEach(() => {
          layerModel = MAP_CTX_LAYER_GEOJSON_REMOTE_FIXTURE
          layer = service.createLayer(layerModel)
        })
        it('create a VectorLayer', () => {
          expect(layer).toBeTruthy()
          expect(layer).toBeInstanceOf(VectorLayer)
        })
        it('create a VectorSource source', () => {
          const source = layer.getSource()
          expect(source).toBeInstanceOf(VectorSource)
        })
        it('sets the format as GeoJSON', () => {
          const source = layer.getSource()
          expect(source.getFormat()).toBeInstanceOf(GeoJSON)
        })
        it('set the url to point to the file', () => {
          const source = layer.getSource()
          expect(source.getUrl()).toBe(layerModel.url)
        })
      })
    })
  })

  describe('#createView', () => {
    describe('from center and zoom', () => {
      let view
      const contextModel = MAP_CTX_FIXTURE
      beforeEach(() => {
        view = service.createView(contextModel.view)
      })
      it('create a view', () => {
        expect(view).toBeTruthy()
        expect(view).toBeInstanceOf(View)
      })
      it('set center', () => {
        const center = view.getCenter()
        expect(center).toEqual(contextModel.view.center)
      })
      it('set zoom', () => {
        const zoom = view.getZoom()
        expect(zoom).toEqual(contextModel.view.zoom)
      })
    })
    describe('from extent', () => {
      let view
      const contextModel = MAP_CTX_FIXTURE
      contextModel.view.extent = MAP_CTX_EXTENT_FIXTURE
      const map = new Map({})
      map.setSize([100, 100])
      beforeEach(() => {
        view = service.createView(contextModel.view, map)
      })
      it('create a view', () => {
        expect(view).toBeTruthy()
        expect(view).toBeInstanceOf(View)
      })
      it('set center', () => {
        const center = view.getCenter()
        expect(center).toEqual([324027.04834895337, 6438563.654151043])
      })
      it('set zoom', () => {
        const zoom = view.getZoom()
        expect(zoom).toEqual(5)
      })
    })
  })
  describe('#resetMapFromContext', () => {
    describe('without config', () => {
      const map = new Map({})
      const mapContext = MAP_CTX_FIXTURE
      beforeEach(() => {
        service.resetMapFromContext(map, mapContext)
      })
      it('create a map', () => {
        expect(map).toBeTruthy()
        expect(map).toBeInstanceOf(Map)
      })
      it('add layers', () => {
        const layers = map.getLayers().getArray()
        expect(layers.length).toEqual(3)
      })
      it('set view', () => {
        const view = map.getView()
        expect(view).toBeTruthy()
        expect(view).toBeInstanceOf(View)
      })
    })
    describe('with config', () => {
      const map = new Map({})
      const mapContext = MAP_CTX_FIXTURE
      const mapConfig = MAP_CONFIG_FIXTURE
      beforeEach(() => {
        mapConfig.DO_NOT_USE_DEFAULT_BASEMAP = true
        service.resetMapFromContext(map, mapContext, mapConfig)
      })
      it('set maxZoom', () => {
        const maxZoom = map.getView().getMaxZoom()
        expect(maxZoom).toBe(10)
      })
      it('set first layer as baselayer', () => {
        const baselayerUrls = (map.getLayers().item(0) as TileLayer<XYZ>)
          .getSource()
          .getUrls()
        expect(baselayerUrls).toEqual(['https://some-basemap-server'])
      })
      it('add one WMS layer from config on top of baselayer', () => {
        const layerWMSUrl = (map.getLayers().item(1) as TileLayer<TileWMS>)
          .getSource()
          .getUrls()[0]
        expect(layerWMSUrl).toEqual('https://some-wms-server')
      })
      it('add one WFS layer from config on top of baselayer', () => {
        const layerWFSSource = (
          map.getLayers().item(2) as VectorLayer<VectorSource<Geometry>>
        ).getSource()
        expect(layerWFSSource).toBeInstanceOf(VectorSource)
      })
    })
    describe('with config, but keeping default basemap', () => {
      const map = new Map({})
      const mapContext = MAP_CTX_FIXTURE
      const mapConfig = MAP_CONFIG_FIXTURE
      beforeEach(() => {
        mapConfig.DO_NOT_USE_DEFAULT_BASEMAP = false
        service.resetMapFromContext(map, mapContext, mapConfig)
      })
      it('set first layer as baselayer', () => {
        const baselayerUrls = (map.getLayers().item(0) as TileLayer<XYZ>)
          .getSource()
          .getUrls()
        expect(baselayerUrls).toEqual(DEFAULT_BASELAYER_CONTEXT.urls)
      })
    })
  })
  describe('#mergeMapConfigWithContext', () => {
    const mapContext = MAP_CTX_FIXTURE
    const mapConfig = MAP_CONFIG_FIXTURE
    beforeEach(() => {
      mapConfig.DO_NOT_USE_DEFAULT_BASEMAP = true
    })
    it('merges mapconfig into existing mapcontext', () => {
      const mergedMapContext = service.mergeMapConfigWithContext(
        mapContext,
        mapConfig
      )
      const layersContext = MAP_CONFIG_FIXTURE.MAP_LAYERS.map(
        service.getContextLayerFromConfig
      )

      expect(mergedMapContext).toEqual({
        ...MAP_CTX_FIXTURE,
        view: {
          ...MAP_CTX_FIXTURE.view,
          maxZoom: MAP_CONFIG_FIXTURE.MAX_ZOOM,
          maxExtent: MAP_CONFIG_FIXTURE.MAX_EXTENT,
        },
        layers: [
          layersContext[0],
          layersContext[1],
          layersContext[2],
          ...MAP_CTX_FIXTURE.layers,
        ],
      })
    })
  })
})
Example #29
Source File: admin_level_data.ts    From prism-frontend with MIT License 4 votes vote down vote up
export function getAdminLevelDataLayerData(
  data: { [key: string]: any }[],
  {
    boundary,
    adminCode,
    dataField,
    featureInfoProps,
  }: Pick<
    AdminLevelDataLayerProps,
    'boundary' | 'adminCode' | 'dataField' | 'featureInfoProps'
  >,
  getState: () => RootState,
) {
  // check unique boundary layer presence into this layer
  // use the boundary once available or
  // use the default boundary singleton instead
  const adminBoundaryLayer =
    boundary !== undefined
      ? (LayerDefinitions[boundary as LayerKey] as BoundaryLayerProps)
      : getBoundaryLayerSingleton();

  const adminBoundariesLayer = layerDataSelector(adminBoundaryLayer.id)(
    getState(),
  ) as LayerData<BoundaryLayerProps> | undefined;
  if (!adminBoundariesLayer || !adminBoundariesLayer.data) {
    // TODO we are assuming here it's already loaded. In the future if layers can be preloaded like boundary this will break.
    throw new Error('Boundary Layer not loaded!');
  }
  const adminBoundaries = adminBoundariesLayer.data;

  const layerData = (data || [])
    .map(point => {
      const adminKey = point[adminCode] as string;
      if (!adminKey) {
        return undefined;
      }
      const value = get(point, dataField);
      const featureInfoPropsValues = Object.keys(featureInfoProps || {}).reduce(
        (obj, item) => {
          return {
            ...obj,
            [item]: point[item],
          };
        },
        {},
      );
      return { adminKey, value, ...featureInfoPropsValues } as DataRecord;
    })
    .filter((v): v is DataRecord => v !== undefined);

  const features = {
    ...adminBoundaries,
    features: adminBoundaries.features
      .map(feature => {
        const { properties } = feature;
        const adminBoundaryCode = get(
          properties,
          adminBoundaryLayer.adminCode,
        ) as string;
        const matchProperties = layerData.find(({ adminKey }) =>
          adminBoundaryCode.startsWith(adminKey),
        );
        if (matchProperties && !isNull(matchProperties.value)) {
          // Do we want support for non-numeric values (like string colors?)
          const value = isString(matchProperties.value)
            ? parseFloat(matchProperties.value)
            : matchProperties.value;
          return {
            ...feature,
            properties: {
              ...properties,
              ...matchProperties,
              // TODO - standardize the field we use to store that data
              // Some functions use "dataField" while others use "data"
              data: value,
              [dataField]: value,
            },
          };
        }
        return undefined;
      })
      .filter(f => f !== undefined),
  } as FeatureCollection;
  return {
    features,
    layerData,
  };
}