How to draw polygon on react native maps with many points(latitude and longitude)?

Fang picture Fang · Nov 20, 2017 · Viewed 13.2k times · Source

I have been following this documentation for drawing polygon on map. Now I tried to fetch the value for latitude and longitude from API and draw it. For a small amount of value, it is not a problem as I just directly wrote it from using state.

Below are my render function

import React, { Component } from 'react';
import { View, Text, StyleSheet, Dimensions } from 'react-native';
import { Card, Button } from 'react-native-elements';
import { MapView } from 'expo';
import { connect } from 'react-redux';

const window = Dimensions.get('window');

class PolygonPage extends Component {
    constructor(props) {
        super(props);

        this.state = {
            polygon: [
            {
                latitude: this.props.points.data.routeGeoJSON.features[0].geometry.coordinates[0][0][1],
                longitude: this.props.points.data.routeGeoJSON.features[0].geometry.coordinates[0][0][0]
            },
            {
                latitude: this.props.points.data.routeGeoJSON.features[0].geometry.coordinates[0][1][1],
                longitude: this.props.points.data.routeGeoJSON.features[0].geometry.coordinates[0][1][0]
            },
            {
                latitude: this.props.points.data.routeGeoJSON.features[0].geometry.coordinates[0][2][1],
                longitude: this.props.points.data.routeGeoJSON.features[0].geometry.coordinates[0][2][0]
            },
            {
                latitude: this.props.points.data.routeGeoJSON.features[0].geometry.coordinates[0][3][1],
                longitude: this.props.points.data.routeGeoJSON.features[0].geometry.coordinates[0][3][0]
            }
        ]
    };
}

onButtonPressClose = () => {
    this.props.navigation.navigate('Home');
}

render() {
    const { polygon } = this.state;
    return (
        <View style={styles.container}>
            <MapView 
                provider={this.props.provider}
                style={styles.map}
                zoomEnabled
                initialRegion={{
                    latitude: this.props.points.data.routeGeoJSON.features[0].geometry.coordinates[0][0][1],
                    longitude: this.props.points.data.routeGeoJSON.features[0].geometry.coordinates[0][0][0],
                        latitudeDelta: 0.0922,
                        longitudeDelta: 0.0421,
                    }}
            >
                <MapView.Polygon
                    coordinates={polygon}
                    fillColor="rgba(0, 200, 0, 0.5)"
                    strokeColor="rgba(0,0,0,0.5)"
                    strokeWidth={2}
                />
            </MapView>
            <View style={stylesContainer.topContainer}>
                <Card title="Route Information">
                    <View>
                        <Text>Name: {this.props.points.data.name}</Text>
                        <Text>Description: {this.props.routes.data.description}</Text>
                    </View>
                </Card>
            </View>
            <View style={stylesContainer.buttonBottomContainer}>
                    <Button
                        medium
                        title="Back"
                        backgroundColor="#94b8b8"
                        onPress={this.onButtonPressClose}
                    />
            </View> 
        </View>
    );
    }
}

PolygonPage.propTypes = {
    provider: MapView.ProviderPropType,
}; 

const styles = StyleSheet.create({
    container: {
        ...StyleSheet.absoluteFillObject,
        justifyContent: 'flex-end',
        alignItems: 'center',
    },
    map: {
        flex: 1,
        height: window.height,
        width: window.width
    }
});

function mapStateToProps({ points }) {
    return { points };
}

export default connect(mapStateToProps)(PolygonPage);

This works for me as it rendered a polygon from the point that I got from API.

My API response is in JSON. This is the example

{
"timestamp": 000111,
"verb": "GET",
"object": "route",
"data": {
    "description": "describe",
    "routeGeoJSON": {
        "type": "FeatureCollection",
        "features": [
            {
                "geometry": {
                    "type": "Polygon",
                    "coordinates": [
                        [
                            [
                                122.18919, // this is longitude
                                4.82948294 // this is latitude
                            ],
                            [
                                124.17318,
                                5.9319319
                            ],
                            [
                                101.131191,
                                2.92492
                            ],
                            [
                                106.01010192,
                                4.492472492
                            ]
                        ]
                    ]
                },
                "type": "Feature",
                "properties": {}
            }
        ]
    },
    "id": 1,
    "routeType": "point",
    "name": "Test"
    }
}

If the points/coordinates is less than 10, than I might probably input it as what I did in my render function. But what if there is more than 10 points(latitude and longitude)? I could not figure how should I use map or for loop function inside this.state = { polygon: [....]}.

I have searched online and found some example like this and this but failed to grab the understanding of it.

If anyone have any idea or kind enough to share his suggestion or boilerplate here, I am very thankful for that.

Thank you.

Answer

Stophface picture Stophface · Jan 22, 2018

You have to map through your response and then transform your coordinates into the type given in the documentation

type LatLng {
  latitude: Number,
  longitude: Number,
}

Assuming your API response is saved in apiResponse, try this. You access your object with keys and array Positions and the you map through your coordinates array.

const polygon = apiResponse.data.routeGeoJSON[0].geometry.coordinates[0].map(coordsArr => { 
    let coords = {
        latitude: coordsArr[1],
        longitude: coordsArr[0],
      }
      return coords;
});

The const polygon is what you give your

<MapView.Polygon
    coordinates={polygon} />