I'm using react-native-maps. Is there any way to draw a polygon and get coordinates of vertices in react-native-maps?
Here's the snippet from my code
import MapView, { PROVIDER_GOOGLE, Marker } from "react-native-maps";
render:
{directions && (
<MapView.Polyline coordinates={directions} strokeWidth={4} />
)}
I am using this function to get the polyline:
export const getDirections = async (pickup, dropoff) => {
let response = await callMapsAPI(pickup, dropoff)
// console.log("Cords of direction res: ", response);
if (response) {
// let respJson = await response.json();
// console.log("Cords of direction res json: ", respJson);
let points = Polyline.decode(response.data.routes[0].overview_polyline.points);
// console.log("Cords of direction res points: ", points);
let coords = points.map((point, index) => {
return {
latitude: point[0],
longitude: point[1]
}
})
return coords
} else return null
}
Where
import Polyline from '#mapbox/polyline';
For React Native, you can use
using PanResponder to track x y and convert to latitude and longitude. You can view it here: https://github.com/dev-event/react-native-maps-draw
Related
const getAgenApi = () => {
this.longitudeNow = parseFloat(106.105104103);
this.latitudeNow = parseFloat(-123.123);
// other code...
};
mymap.on("geosearch/showlocation", function (result) {
console.log(result);
// Remove marker
marke.forEach(function (maker) {
mymap.removeLayer(maker);
});
this.longitudeNow = result.location.x;
this.latitudeNow = result.location.y;
// Draw updated locations!
GetAgenApi();
});
Can anyone fix this code to update the latitude and longitude?
As Pi and Mash wrote in comment, your variables are out of scope.
You have to convert mymap.on callback to use arrow function:
mymap.on("geosearch/showlocation", (result) => {
// Now this.longitudeNow points valid variable
this.longitudeNow = result.location.x;
// ...
});
I am trying to insert a .obj file into a React Native app built using Expo.
From the examples I've found that are successfully working, most of these seem to rely on building spheres or cubes within the rendering. I haven't found a good example with a successful rendering of a local file, specifically .obj.
I'm using the expo-three documentation which describes rendering with obj files, but no working examples.
This is what I have so far, which is not producing any rendered object. But want to know if I am on the right track with this, and what I am missing to get the object to render.
Below is the current file code.
import { Renderer, TextureLoader } from 'expo-three';
import * as React from 'react';
import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader';
import {
AmbientLight,
Fog,
GridHelper,
PerspectiveCamera,
PointLight,
Scene,
SpotLight,
} from 'three';
import { Asset } from 'expo-asset';
import { MTLLoader } from 'three/examples/jsm/loaders/MTLLoader';
export default function ThreeDPhytosaur() {
return (
<GLView
style={{ flex: 1 }}
onContextCreate={async (gl) => {
const { drawingBufferWidth: width, drawingBufferHeight: height } = gl;
const sceneColor = 0x6ad6f0;
const renderer = new Renderer({ gl });
renderer.setSize(width, height);
renderer.setClearColor(sceneColor);
const camera = new PerspectiveCamera(70, width / height, 0.01, 1000);
camera.position.set(2, 5, 5);
const scene = new Scene();
scene.fog = new Fog(sceneColor, 1, 10000);
scene.add(new GridHelper(10, 10));
const ambientLight = new AmbientLight(0x101010);
scene.add(ambientLight);
const pointLight = new PointLight(0xffffff, 2, 1000, 1);
pointLight.position.set(0, 200, 200);
scene.add(pointLight);
const spotLight = new SpotLight(0xffffff, 0.5);
spotLight.position.set(0, 500, 100);
spotLight.lookAt(scene.position);
scene.add(spotLight);
const asset = Asset.fromModule(model['phytosaur']);
await asset.downloadAsync();
const objectLoader = new OBJLoader();
const object = await objectLoader.loadAsync(asset.uri);
object.scale.set(0.025, 0.025, 0.025);
scene.add(object);
camera.lookAt(object.position);
const render = () => {
timeout = requestAnimationFrame(render);
renderer.render(scene, camera);
gl.endFrameEXP();
};
render();
}}
/>
);
}
const model = {
'phytosaur': require('../assets/phytosaur.obj'),
};
Thanks very much!
This is the code that I got to render the obj file. Changed the structure of the original file based on some other examples found.
But this might help someone else!
import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader.js';
import { Asset } from 'expo-asset';
import { Renderer} from 'expo-three';
import * as React from 'react';
import {
AmbientLight,
Fog,
PerspectiveCamera,
PointLight,
Scene,
SpotLight,
} from 'three';
export default function ThreeDTwo() {
let timeout;
React.useEffect(() => {
// Clear the animation loop when the component unmounts
return () => clearTimeout(timeout);
}, []);
return (
<GLView
style={{ flex: 1 }}
onContextCreate={async (gl) => {
const { drawingBufferWidth: width, drawingBufferHeight: height } = gl;
const sceneColor = 668096;
// Create a WebGLRenderer without a DOM element
const renderer = new Renderer({ gl });
renderer.setSize(width, height);
renderer.setClearColor(0x668096);
const camera = new PerspectiveCamera(70, width / height, 0.01, 1000);
camera.position.set(2, 5, 5);
const scene = new Scene();
scene.fog = new Fog(sceneColor, 1, 10000);
const ambientLight = new AmbientLight(0x101010);
scene.add(ambientLight);
const pointLight = new PointLight(0xffffff, 2, 1000, 1);
pointLight.position.set(0, 200, 200);
scene.add(pointLight);
const spotLight = new SpotLight(0xffffff, 0.5);
spotLight.position.set(0, 500, 100);
spotLight.lookAt(scene.position);
scene.add(spotLight);
const asset = Asset.fromModule(require("../assets/phytosaur_without_mtl.obj"));
await asset.downloadAsync();
// instantiate a loader
const loader = new OBJLoader();
// load a resource
loader.load(
// resource URL
asset.localUri,
// called when resource is loaded
function ( object ) {
object.scale.set(0.065, 0.065, 0.065)
scene.add( object );
camera.lookAt(object.position)
//rotate my obj file
function rotateObject(object, degreeX=0, degreeY=0, degreeZ=0) {
object.rotateX(THREE.Math.degToRad(degreeX));
object.rotateY(THREE.Math.degToRad(degreeY));
object.rotateZ(THREE.Math.degToRad(degreeZ));
}
// usage:
rotateObject(object, 0, 0, 70);
//animate rotation
function update() {
object.rotation.x += 0.015
}
const render = () => {
timeout = requestAnimationFrame(render);
update();
renderer.render(scene, camera);
gl.endFrameEXP();
};
render();
},
// called when loading is in progresses
function ( xhr ) {
console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );
},
// called when loading has errors
function ( error ) {
console.log( error );
}
);
}}
/>
);
}
I have an app, where I take a pic and draw it to the pdf file.
I have been trying to get them in right ratio. If I take all picture horizontal, it would be fine. If I take all pictures vertical, it would be fine. Problem is, when I take both vertical and horizontal, last picture's ratio applied to all pictures.
I save image ratio to AsyncStorage, where I get it in other component.
Questions is: How can I keep original ratios when I take pictures both ways?
Camera component -> takePicture function:
takePicture = async() => {
if (this.camera) {
const options = { quality: 0.5, base64: true , fixOrientation: true};
const data = await this.camera.takePictureAsync(options);
console.log(data.uri);
Image.getSize(data.uri, (width, height) => { // Get image height and width
let imageWidth = width;
let imageHeight = height;
let stringImageWidth = '' + imageWidth; // Convert to string for AsyncStorage saving
let stringImageHeight = '' + imageHeight;
const horizontalRatioCalc = () => { // return ratio for own variable
return (imageWidth/imageHeight);
};
const verticalRatioCalc = () => {
return (imageWidth/imageHeight);
};
horizontalImageRatio = horizontalRatioCalc();
verticalImageRatio = verticalRatioCalc();
stringHorizontalImageRatio = '' + horizontalImageRatio;
stringVerticalImageRatio = '' + verticalImageRatio;
console.log(`Size of the picture ${imageWidth}x${imageHeight}`);
horizontalRatio = async () => {
if (imageHeight>imageWidth) {
verticalRatioCalc();
try {
AsyncStorage.setItem("imageVerticalRatio", stringVerticalImageRatio),
AsyncStorage.setItem("asyncimageWidth", stringImageWidth),
AsyncStorage.setItem("asyncimageHeight", stringImageHeight),
console.log(`Vertical ratio saved! It's ${stringVerticalImageRatio}`),
console.log(`Image Width saved! It's ${stringImageWidth}`),
console.log(`Image height saved! It's ${stringImageHeight}`)
} catch (e) {
console.log(`AsyncStorage saving of image vertical ratio cannot be done.`)
}
}if (imageHeight<imageWidth) {
horizontalRatioCalc();
try {
AsyncStorage.setItem("imageHorizontalRatio", stringHorizontalImageRatio),
AsyncStorage.setItem("asyncimageWidth", stringImageWidth),
AsyncStorage.setItem("asyncimageHeight", stringImageHeight),
console.log(`Horizontal ratio saved! It's ${stringHorizontalImageRatio}`),
console.log(`Image Width saved! It's ${stringImageWidth}`),
console.log(`Image height saved! It's ${stringImageHeight}`)
} catch (e) {
console.log(`AsyncStorage saving of image vertical ratio cannot be done.`)
}
}
}
horizontalRatio();
}, (error) => {
console.error(`Cannot size of the image: ${error.message}`);
});
back(data.uri)
//CameraRoll.saveToCameraRoll(data.uri).then((data) => {
// console.log(data)
//back(data);
//}).catch((error) => {
//console.log(error)
//})
}
CreatePdf component -> PDF drawing function:
readData = async () => {
try {
kuvakorkeus = await AsyncStorage.getItem('asyncimageHeight')
kuvaleveys = await AsyncStorage.getItem('asyncimageWidth')
vertikaaliratio = await AsyncStorage.getItem('imageVerticalRatio')
horisontaaliratio = await AsyncStorage.getItem('imageHorizontalRatio')
if (kuvakorkeus !== null) {
return kuvakorkeus;
return kuvaleveys;
return vertikaaliratio;
return horisontaaliratio;
}
} catch (e) {
alert('Failed to fetch the data from storage')
}
}
readData ();
kuvanpiirto = () => {
pdfKuvaKorkeus = 100;
if(kuvakorkeus>kuvaleveys) { // VERTICAL / PYSTYKUVA
page.drawImage(arr[i].path.substring(7),'jpg',{
x: imgX,
y: imgY,
width: pdfKuvaKorkeus*vertikaaliratio,
height: pdfKuvaKorkeus,
})
}
if(kuvakorkeus<kuvaleveys) { // Horizontal / Vaakakuva
page.drawImage(arr[i].path.substring(7),'jpg',{
x: imgX,
y: imgY,
width: pdfKuvaKorkeus*horisontaaliratio,
height: pdfKuvaKorkeus,
})
}
}
kuvanpiirto();
I want to produce an Animated.Value that is the result of dividing a constant by another Animated.Value.
const originalSize = 255;
const currentSize = this.props.someAnimatedValue;
// This method doesn't exist, but it's what I want:
const animatedScaleFactor = Animated.divide(originalSize, currentSize);
```
Since there is no Animated.divide() method, I only have at my disposal someAnimatedValue.interpolate(), which I can use to map an input range to an output range with a custom easing curve, Animated.multiply(), and Animated.modulus().
Any ideas?
UPDATE - use Animated.Divide instead.
Old answer:
Figured out how to get what I want f(x) = 1/x using an interpolator and custom easing function:
import React, {
Animated,
Component,
View
} from 'react-native';
export default class EasingTest extends Component {
state = {
input: new Animated.Value(0)
};
componentDidMount() {
const max = 937;
const output = this.state.input.interpolate({
inputRange: [0,max],
outputRange: [0,1/max],
easing: t => 1 / t
});
setInterval(() => {
const input = this.state.input.__getValue();
const expected = 1 / input;
const actual = output.__getValue();
const error = Math.abs(expected - actual) / max;
console.info(`f(${input}) = ${actual} (expected ${expected}, error ${Math.round(error * 100)}%`);
}, 200);
Animated.timing(this.state.input, {
toValue: max,
duration: 1000
}).start();
}
render() {
return <View />
}
}
I have an app that calls an api and returns a list of locations.
Once the data is returned, I convert the JSON to map points for annotations.
These get added to the ma with no problem.
The problem I am running into is setting the bounds of the map. I can't seem to figure it out.
The code I currently have is.
_handleResponse(response) {
var locations = [];
// Loop through repsone and add items to an arra for annotations
for (var i = 0; i < response.length; i++) {
// Get the location
var location = response[i];
// Parse the co ords
var lat = parseFloat(location.Latitude);
var lng = parseFloat(location.Longitude);
// Add the location to array
locations.push({
latitude: lat,
longitude: lng,
title: location.Name
});
}
// This calls the map set state
this.setState({
annotations: locations
});
}
and here is my view code
<View style={styles.container}>
<MapView
style={styles.map}
onRegionChangeComplete={this._onRegionChangeComplete}
annotations={this.state.annotations}
/>
</View>
You'll want
<MapView
...
region={region}
/>
where
var region = {
latitude,
longitude,
latitudeDelta,
longitudeDelta,
};
latitude and longitude are the center of the map and the deltas are the distance (in degrees) between the minimum and maximum lat/long shown. For instance, given a certain radius in miles around a point and an aspect ratio of the map view, you could calculate region as follows:
var radiusInRad = radiusInKM / earthRadiusInKM;
var longitudeDelta = rad2deg(radiusInRad / Math.cos(deg2rad(latitude)));
var latitudeDelta = aspectRatio * rad2deg(radiusInRad);
The definitions of rad2deg, deg2rad, and earthRadiusInKM are left as an exercise to the reader.
Here is my complete code based on #Philipp's answer:
import React, { Component } from 'react';
import { MapView } from 'react-native';
const earthRadiusInKM = 6371;
// you can customize these two values based on your needs
const radiusInKM = 1;
const aspectRatio = 1;
class Map extends Component {
constructor(props) {
super(props);
// this will be the map's initial region
this.state = {
region : {
latitude: 0,
longitude: 0
}
};
}
// you need to invoke this method to update your map's region.
showRegion(locationCoords) {
if (locationCoords && locationCoords.latitude && locationCoords.longitude) {
var radiusInRad = radiusInKM / earthRadiusInKM;
var longitudeDelta = this.rad2deg(radiusInRad / Math.cos(this.deg2rad(locationCoords.latitude)));
var latitudeDelta = aspectRatio * this.rad2deg(radiusInRad);
this.setState({
region: { latitude: locationCoords.latitude, longitude: locationCoords.longitude, latitudeDelta: latitudeDelta, longitudeDelta: longitudeDelta }
});
}
}
render () {
return (
<MapView
style={{flex: 1}}
region={this.state.region}/>
)
}
deg2rad (angle) {
return angle * 0.017453292519943295 // (angle / 180) * Math.PI;
}
rad2deg (angle) {
return angle * 57.29577951308232 // angle / Math.PI * 180
}
}