英文:
How to create full world map in react native?
问题
我想创建一个完整的世界地图,在其中可以根据提供的数据绘制一些点。
我已经尝试了许多React Native库,但没有从中获得任何解决方案。
英文:
I want to create a full world map where I can plot some points based on provided data.
I have tried many libraries in react native but I am not getting any solutions from it.
This is an image of what I am trying to achieve using react native.
答案1
得分: 4
解决方案
你可以使用SVG来创建这样的地图,方法是找到一个世界地图的SVG文件,并跟踪SVG地图中各个国家的位置。利用这些位置信息,你可以在各个国家周围绘制圆圈。
先决条件
我建议阅读这篇文章以更好地理解SVG Path。
渲染地图
步骤1
下载一个SVG世界地图。在SVG地图图像中,你需要以下内容:
- 每个国家都应该使用单独的SVG路径进行绘制,以定位国家或附近地区。
- SVG应该是可伸缩的。
我从SimpleMaps下载了SVG地图。这里的地图具备我上面提到的两个条件。你可以选择下载具有自定义高度/宽度的地图,每个国家都用单独的路径进行绘制。
步骤2
将下载的SVG转换为JSX,有许多在线转换工具可用,这个是我使用的一个。现在将这个转换后的JSX渲染到屏幕上。
这样,我们就完成了地图的渲染。
绘制圆圈
步骤1
在下载SVG地图时,我们检查到每个国家都是用单独的路径绘制的。你还可以注意到每个路径都有一个id或类名,以国家的名称命名。这个名称可能是缩写。这是我们找到各个国家路径的方法。
步骤2
要理解这一部分,首先必须阅读这篇文章。
现在假设印度的地图路径以M223.14 53.577
开头,这意味着在整个世界地图中,我们可以在这个点(223.1, 53.577)找到印度的位置。通过这种方式,你可以获取地图上任何国家的位置。我们可以使用这个点来绘制一个圆圈。
步骤3
要在这个点上绘制圆圈,我们将使用react-native-svg
中的Circle
,
在SVG标签结束之前绘制这个圆圈,就像这样:
...
<Circle cx={223.14} cy={53.577} r={5} fill={'red'}/>
</Svg>
请注意,从路径中获得的位置位于国家的边界上,你可能需要微调位置以将圆圈放置在所需的位置上。
结果
我创建了这个示例,使用了我从上面建议的网站下载的免费地图,你可以参考它。我在这里放置了一个圆圈在英国上。如前所述,你也可以下载具有自定义尺寸的地图,但我认为那是不免费使用的,所以我没有在示例中使用自定义尺寸的地图,但你需要一个具有自定义尺寸的地图以适应移动屏幕。
编辑
查看这个示例,我将3个国家映射到一个对象中,并使用了你分享的相同API响应。它还可以动态工作,你现在只需按其位置添加更多的国家。我在这里使用了这个SVG世界地图。
我将你分享的API响应传递给了WorldMap组件:
<WorldMap apiResponse={apiResponse} />
在WorldMap
组件中,我将国家的位置映射到它们的ID,如下所示:
const COUTRIES = {
'ZA' : [562.70375, 527.0484],
'GB' : [471.90475,298.2024],
'US' : [79.174748,187.7204],
}
要绘制圆圈,我在SVG的末尾添加了Circle:
{
props.apiResponse.map(country =>
<Circle cx={COUTRIES[country.id][0]} cy={COUTRIES[country.id][1]} r={10} fill={'red'} key={country.id} />
)
}
现在,你只需更新COUNTRIES
对象,将每个国家的ID和位置添加进去,它将动态地在地图上绘制圆圈。
截图
英文:
Solution
You can create such map using SVGs, by finding a world map SVG and tracking the locations of the countries in this SVG map. Using these locations, you can plot Circles around the countries.
Prerequisite
I would suggest reading this to get better understanding of the SVG Path.
Render the Map
Step 1
Download an SVG world map. Things you will need in the svg map image are,
- Each country should be drawn using a separate SVG Path to locate country or nearby region.
- SVG should be scalable.
I downloaded svg map from SimpleMaps. Here maps have both of the things I mentioned above. You have option to download maps with custom height/width and each country is drawn with separate path.
Step 2
Convert the downloaded SVG into JSX, there are many converters available online, this is the one I use.
Now render this converted JSX on the screen.
With this, we are done with the map.
Plot The Circles
Step 1
While downloading the SVG map, we checked that each country is drawn using separate path, You can also notice that each of this path is having an id or class named after a country. This name may be shorthand. This is how we find path for respective countries.
Step 2
To understand this part, it is must to read this first.
Now suppose India's map path starts with M223.14 53.577
, which means in the whole world map, we will get India's location at this point(223.1, 53.577). In this way you can get location of any country in the map using the path. We can use this point to plot a circle.
Step 3
To plot circle on this point, we will use Circle
from react-native-svg
,
Draw this circle at the end on the svg, just before closing Svg tag like this,
...
<Circle cx={223.14} cy={53.577} r={5} fill={'red'}/>
</Svg>
Note that the location you get from the Path is on border of the country, you may need to tweak the location to get the circle on your desired location.
Result
I have created this snack with free to use map which I downloaded from above suggested site, you may follow it, I have plotted a circle on United kingdom here. As mentioned earlier, you can download map svg in custom dimensions also but I think that is not free to use, so I have not used custom dimension map in it, but you will need a map with custom dimensions to make it fit on mobile screen.
EDIT
check this snack, I have mapped 3 countries in a object and used same api reponse shared by you. It is working DYNAMICALLY also, you now just have to add more countries by there location. I am using this svg world map here.
I have passed the api response shared by you to the worldmap component
<WorldMap apiResponse={apiResponse} />
In the WorldMap
component, I have mapped countries locations to their IDs like this,
const COUTRIES = {
'ZA' : [562.70375, 527.0484],
'GB' : [471.90475,298.2024],
'US' : [79.174748,187.7204],
}
And to plot circles, I have added Circle at the end of the SVG,
{
props.apiResponse.map(country =>
<Circle cx={COUTRIES[country.id][0]} cy={COUTRIES[country.id][1]} r={10} fill={'red'} key={country.id} />
)
}
Now you just have to update COUNTRIES
object with each country ID and location,
and it will plot the circles on the map dynamically.
Screenshot
答案2
得分: 0
考虑使用完整的地图 SDK,例如 Mapbox、MapLibre 或 Google 地图,并托管自定义瓦片集。
为什么使用地图 SDK?
- 用图像进行所有这些计算可能有效,但可能会耗时、容易出错,需要大量测试。相较之下,地图 SDK 已经包含了大部分计算。
- 地图特定功能,如显示当前位置。地图 SDK 能很好地实现这些。
例如,Mapbox 允许自定义地图样式,你可以直接托管自己的瓦片/图层。在这里查看。
大多数这些服务都有一个适用于 React Native 的变体。例如
这些服务将允许你使用世界坐标准确地将点放在地图上。你需要为你的图钉添加一个符号图层,将自定义图像添加为源,并将位置与符号类型相匹配的坐标固定在地图上。
英文:
Consider using a full map sdk such as mapbox, maplibre, or Google maps and host a custom tileset.
Why use a map sdk?
- Doing all these calculations with an image may work, but it could be time intensive, error prone, require a bunch of testing. VS map-sdk already shipping most of the calculations.
- map specific features. Like showing current location. Map sdks do that well.
Example Mapbox allows for custom map styling and you can host your own tiles/layers directly. See here
Most of these services have a react-native variant. Example
These services would allow you to use world coordinates to accurately put points on your map. You will need to add a symbol layer for your pins, add the custom images as sources and pin the locations on the map using coordinates matched with the symbol type.
答案3
得分: 0
import the map to react native as jpg for better performance and load time speed, then create a pressable, within that pressable create a circle and then create another view and set it's visibility to a hook boolean variable called visible, inside that View create a text tag that will display the data, when the pressable is pressed the useState hook will update the page and set visible to true.
const Car = (props) => {
if (props.visibility == true) {
return (<View><Text>Data</Text></View>)
}
else {
return 0;
}
}
const Map = () => {
const [visible, setvisible] = useState(false);
return (
<Image width={400} height={200} src={require('path')}/>
<Pressable onPress={() => setvisible(true)}>
<View style={{ borderRadius: 50, backgroundColor: 'red', marginTop: 50, marginLeft: 50 }}/>
</Pressable>
<Card visibility={visible}/>
);
}
Note: I've provided the translation of the code as requested.
英文:
import the map to react native as jpg for better performance and load time speed, then create a pressable, within that pressable create a circle and then create another view and set it's visibility to a hook boolean variable called visible, inside that View create a text tag that will display the data, when the pressable is pressed the useState hook will update the page and set visible to true.
<!-- begin snippet: js hide: false console: false babel: false -->
<!-- language: lang-js -->
const Car = (props) =>{
if(props.visibility == true){
return (<View><Text>Data</Text></View>)
}
else{
return 0;
}
const Map = () => {
const [visible, setvisible] = useState(false);
return(
<Image width={400} height={200} src={require('path')}/>
<Pressable onPress={()=> setvisible(true)}>
<View style={{borderRadius:50,backgroundColor:'red', marginTop: 50, marginLeft:50}}/>
</Pressable>
<Card visibility={visible}/>
);
}
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论