>  기사  >  백엔드 개발  >  Python folium의 기능을 사용하는 방법

Python folium의 기능을 사용하는 방법

WBOY
WBOY앞으로
2023-05-23 21:55:461555검색

1. 렌더링

Python folium의 기능을 사용하는 방법

2. 레이어 제어

Folium 공식은 또한 우리가 사용할 수 있는 몇 가지 명확한 방법을 제공합니다. 레이어 제어와 같습니다. 공식 메서드 이름은 FeatureGroup이고 가져오기 메서드는 folium import FeatureGroup 또는 folium.FeatureGroup()에서 가져옵니다. 여기서는 구체적인 원리에 대해 자세히 설명하지 않고 주로 예를 살펴보겠습니다.

import folium

def map2png(map_data,out_file='pdf.png'):
	# 1.直接构造,默认底图
	mo = folium.Map(location=[0, 0])
	
    # 2.图层1-高德底图+数据
    fg = folium.FeatureGroup()
    # 2.1 高德地图
    fg.add_child(folium.TileLayer(
        tiles='http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}',
        attr="&copy; <a href=http://ditu.amap.com/>高德地图</a>",
        min_zoom=0,
        max_zoom=19,
        control=True,
        zoom_control=False,
        show=True))
    # 2.2添加一个点
    fg.add_child(folium.Marker(
							location=[45.3311, -121.7113],
							popup="Timberline Lodge",
							icon=folium.Icon(color="green")))
  	#  2.3添加一个线形   
	fg.add_child(folium.PolyLine(
		locations=[[38.68,115.67],
					[38.85,115.48],
					[38.65,115.37],
					[38.68,115.67]],
		color=&#39;green&#39;, weight=2, opacity=1))
 	# 2.4添加一个面
	fg.add_child(folium.Polygon(
	    locations=[[38.68,115.67],
					[38.85,115.48],
					[38.65,115.37],
					[38.68,115.67]], 
		color=&#39;green&#39;, weight=2, 
		fill=True,fill_color = &#39;red&#39;))
	# 2.5将我们的图层加入map
	mo.add_child(fg)
	
	# 3.图层2-重点数据+最上层
	fg2 = folium.FeatureGroup()
	fg2.add_child(folium.Polygon(
	    locations=[[38.68,115.67],
					[38.85,115.48],
					[38.65,115.37],
					[38.68,115.67]], 
		color=&#39;green&#39;, weight=2, 
		fill=True,fill_color = &#39;red&#39;))
	mo.add_child(fg2)
	
	# 4.将图层fg2显示在最上层,keep_in_front的参数必须是FeatureGroup或TileLayer对象
	mo.keep_in_front(fg2)
	
	# 5.根据范围缩放地图
    mo.fit_bounds([[38.68,115.67],
					[38.85,115.48],
					[38.65,115.37],
					[38.68,115.67]])  
					
    root = mo.get_root()
    html = root.render()  # 这个拿到的就是一个html的内容
    # mo.save(&#39;text.html&#39;)

3. 북쪽 포인터

북쪽 포인터 기능은 지도에 반드시 필요한 것은 아니지만 항상 추가하는 것이 좋습니다. 공식 문서 및 소스 코드 분석에는 관련 내용이 언급되어 있지 않지만 FloatImage를 사용하면 이 기능을 수행할 수 있습니다. 공식 문서에는 많은 플러그인이 제공되어 있으며, 그 중 가장 널리 사용되는 것은 히트맵이라는 HeatMap 방법입니다.

FloatImage 메서드는 화면에 이미지를 배치하고 이미지의 크기와 화면의 위치를 ​​지정하는 것을 구현합니다. 매개변수는 정수입니다(FloatImage 메서드는 백분율 변환을 구현합니다). 두 번째 코드를 기반으로 왼쪽 하단에 이미지를 추가했습니다.

fg.add_child(FloatImage(os.path.join(base, &#39;map_png&#39;, &#39;image&#39;, &#39;compass.png&#39;), left=5, bottom=10, width=5))

4. folium에 js 및 css 추가

folium은 공식적으로 js 및 css를 추가하는 관련 메소드를 제공하지 않습니다. 인터넷에 있는 많은 메소드는 소스 코드 해석을 기반으로 추출되어야 하며 상대적으로 간단하며 구체적인 지침이 없습니다. . 관련 지침을 보려면 js 및 css를 추가하세요.

Folium의 지도 기능은 jinjia2를 통해 구현되어 데이터 및 지도용 HTML을 로드하는 것을 소스 코드에서 알 수 있습니다.

소스코드에 사용되는 데이터와 지도를 추가하는 방법은 크게 3가지가 있습니다. 이러한 방법에는 결함이 있습니다(앞에만 추가할 수 있음). 이러한 방법은 대부분의 시나리오에서 사용할 수 있습니다. 맵 개체에 대한 작업이 포함되지 않으면 이 세 가지 방법이 요구 사항을 충족할 수 있습니다.

1.header는 js 및 css를 추가합니다

    init_script = """
        var mapsPlaceholder = [];
        L.Map.addInitHook(function () {mapsPlaceholder.push(this);});
    """
    # 加在header最上边
    mo.get_root().header.add_child(folium.Element(init_script))

Python folium의 기능을 사용하는 방법

2.body는 js 및 css를 추가합니다

    init_script = """
        var mapsPlaceholder = [];
        L.Map.addInitHook(function () {mapsPlaceholder.push(this);});
    """
    # 加在body中
    mo.get_root().html.add_child(folium.Element(init_script))

Python folium의 기능을 사용하는 방법

3.script는 js 및 css

    init_script = """
        var mapsPlaceholder = [];
        L.Map.addInitHook(function () {mapsPlaceholder.push(this);});
    """
    # 加在script中
    mo.get_root().script.add_child(folium.Element(init_script))

Python folium의 기능을 사용하는 방법

5를 추가합니다.

Up 한 단계에서는 html 파일의 서로 다른 위치에 js와 css를 추가하는 방법이 구현됩니다. 지도 객체의 작업과 관련된 경우 경도 및 위도 격자선이 추가되는 등 만족스럽지 못한 상황이 발생할 수 있습니다. 위도 및 경도 격자선 기능을 구현하는 것이 번거롭습니다.

1. 공식적인 관련 방법 및 플러그인이 없습니다(현재 없음).

2. 위도와 경도를 구현하기 위해 Leadlet.js를 사용하는 라이브러리입니다. 전단지에 대해 잘 알고 있어야 합니다. (인터넷에서 관련 기사가 하나만 발견되었습니다.)

3 위 기사는 프런트 엔드로 완성되었습니다. 직접 백엔드 구현 방법.

4. 프론트엔드 구현 방식은 지도를 직접 생성하는 방식입니다. 여기서는 지도 생성 객체를 사용할 수 없습니다(지도 객체는 무작위로 생성됩니다).

위도와 경도 격자선을 결정하는 방법은 무엇입니까?

지도 객체를 생성할 때 객체를 저장한 다음 지도 객체를 가져와 확대/축소 수준에 따라 그리드 선을 구현해야 합니다. 중요한 작업은 지도 객체를 생성하기 전후에 JavaScript 코드가 HTML 페이지에 올바르게 삽입되었는지 확인하는 것입니다.

그 중 맵 객체 생성 시 객체를 4개로 저장하는 방식을 구현했습니다. Folium 소스 코드를 연구하여 맵 객체 생성 후 j를 추가하도록 js를 추가하는 방법을 다시 작성했습니다.

Python folium의 기능을 사용하는 방법

1.html 위도 경도 그리드 구현 페이지

Python folium의 기능을 사용하는 방법

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
 
    <link
      rel="stylesheet"
      href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" rel="external nofollow" 
    />
    <script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"></script>
 
    <title>leaflet-经纬网格</title>
    <style>
      html,
      body {
        width: 100%;
        height: 100%;
        padding: 0;
        margin: 0;
      }
      .leaflet-div-icon {
        background: none;
        border: none;
      }
    </style>
  </head>
 
  <body>
    <div id="map" ></div>
 
    <script>
      let map = L.map("map", { renderer: L.canvas({ padding: 0.5 }) }).setView(
        [25.127879288597576, 118.37905883789064],
        4
      );
      // 添加背景图层
      L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
        attribution:
          &#39;&copy; <a href="https://www.openstreetmap.org/copyright" rel="external nofollow" >OpenStreetMap</a> contributors&#39;,
      }).addTo(map);
 
      // 创建图层
      let lonLatGridLineLayer = L.featureGroup().addTo(map);
      // 经纬网格生成方法
      let addLonLatLine = () => {
        let zoom = map.getZoom();
        let bounds = map.getBounds();
        let north = bounds.getNorth();
        let east = bounds.getEast();
        // 经纬度间隔
        let d = 90 / Math.pow(2, zoom - 1);
        // 经线网格
        for (let index = -180; index <= 360; index += d) {
          // 判断当前视野内
          if (bounds.contains([north, index])) {
            // 绘制经线
            let lonLine = L.polyline(
              [
                [-90, index],
                [90, index],
              ],
              { weight: 1, color: "blue" }
            );
            lonLatGridLineLayer.addLayer(lonLine);
            // 标注
            let text = index.toFixed(1) + "°";
            // 动态计算小数位数
            if (zoom > 10) {
              text = index.toFixed((zoom - 8) / 2) + "°";
            }
            let divIcon = L.divIcon({
              html: `<div >${text}</div>`,
              iconAnchor: [0, -5],
            });
            let textMarker = L.marker([north, index], { icon: divIcon });
            lonLatGridLineLayer.addLayer(textMarker);
          }
        }
		if(d>90)d=90;
        // 纬线网格
        for (let index = -90; index <= 90; index += d) {
          if (bounds.contains([index, east])) {
            let lonLine = L.polyline(
              [
                [index, -180],
                [index, 360],
              ],
              { weight: 1, color: "blue" }
            );
            lonLatGridLineLayer.addLayer(lonLine);
            // 标注
            let text = index.toFixed(1) + "°";
            if (zoom > 10) {
              text = index.toFixed((zoom - 8) / 2) + "°";
            }
            let divIcon = L.divIcon({
              html: `<div >${text}</div>`,
              iconAnchor: [(text.length + 1) * 6, 0],
            });
            let textMarker = L.marker([index, east], { icon: divIcon });
            lonLatGridLineLayer.addLayer(textMarker);
          }
        }
      };
      addLonLatLine();
      map.on("zoomend move", () => {
        lonLatGridLineLayer.clearLayers();
        addLonLatLine();
      });
    </script>
  </body>
</html>

2. 그리드 라인 클래스 커스터마이징

소스 코드의 클래스 상속 관계를 통해 MacroElement 클래스를 상속받았습니다.

from branca.element import MacroElement,
from jinja2 import Template
from folium.vector_layers import path_options

class Jwwg(MacroElement):
    """自定义经纬线网格"""
    _template = Template("""
        {% macro script(this, kwargs) %}
                    var map = mapsPlaceholder.pop();
                    // 创建图层
                    let lonLatGridLineLayer = L.featureGroup().addTo(map);
                    // 经纬网格生成方法
                    let addLonLatLine = () => {
                        let zoom = map.getZoom();
                        let bounds = map.getBounds();
                        let north = bounds.getNorth();
                        let east = bounds.getEast();
                        // 经纬度间隔
                        let d = 90 / Math.pow(2, zoom - 1);
                        // 经线网格
                        for (let index = -180; index <= 360; index += d) {
                            // 判断当前视野内
                            if (bounds.contains([north, index])) {
                                // 绘制经线
                                let lonLine = L.polyline(
                                    [
                                        [-90, index],
                                        [90, index],
                                    ],
                                    {weight: 1, color: "blue"}
                                );
                                lonLatGridLineLayer.addLayer(lonLine);
                                // 标注
                                let text = index.toFixed(1) + "°";
                                // 动态计算小数位数
                                if (zoom > 10) {
                                    text = index.toFixed((zoom - 8) / 2) + "°";
                                }
                                let divIcon = L.divIcon({
                                    html: `<div >${text}</div>`,
                                    iconAnchor: [0, -5],
                                });
                                let textMarker = L.marker([north, index], {icon: divIcon});
                                lonLatGridLineLayer.addLayer(textMarker);
                            }
                        }
                        if (d > 90) d = 90;
                        // 纬线网格
                        for (let index = -90; index <= 90; index += d) {
                            if (bounds.contains([index, east])) {
                                let lonLine = L.polyline(
                                    [
                                        [index, -180],
                                        [index, 360],
                                    ],
                                    {weight: 1, color: "blue"}
                                );
                                lonLatGridLineLayer.addLayer(lonLine);
                                // 标注
                                let text = index.toFixed(1) + "°";
                                if (zoom > 10) {
                                    text = index.toFixed((zoom - 8) / 2) + "°";
                                }
                                let divIcon = L.divIcon({
                                    html: `<div >${text}</div>`,
                                    iconAnchor: [(text.length + 1) * 6, 0],
                                });
                                let textMarker = L.marker([index, east], {icon: divIcon});
                                lonLatGridLineLayer.addLayer(textMarker);
                            }
                        }
                    };
                    addLonLatLine();
                    map.on("zoomend move", () => {
                        lonLatGridLineLayer.clearLayers();
                        addLonLatLine();
                    });
                   {% endmacro %}
                """)

    def __init__(self, **kwargs):
        super(Jwwg, self).__init__()
        self._name = &#39;Jwwg&#39;
        self.options = path_options(line=True, **kwargs)

3. 그리드 선 구현

import folium

def map2png(map_data,out_file=&#39;pdf.png&#39;):
	# 1.直接构造,默认底图
	mo = folium.Map(location=[0, 0])
	
    # 2.图层1-高德底图+数据
    fg = folium.FeatureGroup()
    # 2.1 高德地图
    fg.add_child(folium.TileLayer(
        tiles=&#39;http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}&#39;,
        attr="&copy; <a href=http://ditu.amap.com/>高德地图</a>",
        min_zoom=0,
        max_zoom=19,
        control=True,
        zoom_control=False,
        show=True))
    # 2.2添加一个点
    fg.add_child(folium.Marker(
							location=[45.3311, -121.7113],
							popup="Timberline Lodge",
							icon=folium.Icon(color="green")))
  	#  2.3添加一个线形   
	fg.add_child(folium.PolyLine(
		locations=[[38.68,115.67],
					[38.85,115.48],
					[38.65,115.37],
					[38.68,115.67]],
		color=&#39;green&#39;, weight=2, opacity=1))
 	# 2.4添加一个面
	fg.add_child(folium.Polygon(
	    locations=[[38.68,115.67],
					[38.85,115.48],
					[38.65,115.37],
					[38.68,115.67]], 
		color=&#39;green&#39;, weight=2, 
		fill=True,fill_color = &#39;red&#39;))
	# 2.5将我们的图层加入map
	mo.add_child(fg)
	# 5.根据范围缩放地图
    mo.fit_bounds([[38.68,115.67],
					[38.85,115.48],
					[38.65,115.37],
					[38.68,115.67]])  
    # 网格线
    init_script = """
        var mapsPlaceholder = [];
        L.Map.addInitHook(function () {mapsPlaceholder.push(this);});
    """			
    mo.get_root().script.add_child(folium.Element(init_script))
   	Jwwg().add_to(mo)
   	
    root = mo.get_root()
    html = root.render()  # 这个拿到的就是一个html的内容
    # mo.save(&#39;text.html&#39;)

위 내용은 Python folium의 기능을 사용하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제