zoukankan      html  css  js  c++  java
  • WRS2数据查询代码(Golang)

    WRS2(全球参考系统)简介

    参考:全球参考系统(WRS)概述及常用工具汇总

    WRS(Worldwide Reference System)是Landsat卫星采用的全球参考系统,也是国际上非常具有代表意义的全球参考系统之一。WRS是依据卫星地面轨迹的重复特性,结合星下点成像特性而形成的固定地面参考网格。其WRS参考系网格与Landsat卫星数据的成像区域紧密的契合,WRS网格的二维坐标采用Path和Row进行标识。
    目前WRS有两个系统,分别为WRS-1(1983年之前)和WRS-2(1983年之后)。Landsat1-3使用WRS-1,Landsat4、5、7、8使用WRS-2。

    WRS2 数据

    这个数据我找了很久,NASA的网站现在只有在线查询的地方,没有找到数据下载。后来在这里 Converting latitude/longitude co-ordinates to Landsat WRS-2 paths/rows 找到了数据的下载位置

    代码

    完整代码请见:https://github.com/sotex/Landsat8cvsToMySQL

    WRS2 查询相关代码如下:

    package main
    
    import (
    	"bytes"
    	"encoding/json"
    	"fmt"
    	"strconv"
    	"strings"
    
    	"github.com/tidwall/geojson"
    
    	"github.com/jonas-p/go-shp"
    	geometry "github.com/tidwall/geojson/geometry"
    )
    
    type (
    	WRS2Object struct {
    		Path     int            // 路径
    		Row      int            // 行
    		boundary *geometry.Poly // 有效范围
    	}
    )
    
    // 转换为 geojson 格式
    func (obj *WRS2Object) MarshalJSON() ([]byte, error) {
    	buf := bytes.NewBuffer(nil)
    	buf.WriteString(`{"type":"Feature","properties":{"path":`)
    	buf.WriteString(strconv.Itoa(obj.Path))
    	buf.WriteString(`,"row":`)
    	buf.WriteString(strconv.Itoa(obj.Row))
    	buf.WriteString(`},"geometry":`)
    	data, err := json.Marshal(geojson.NewPolygon(obj.boundary))
    	if err != nil {
    		return nil, err
    	}
    	buf.Write(data)
    	buf.WriteByte('}')
    	return buf.Bytes(), err
    }
    
    var (
    	// WRS2索引 key=path*1000+row
    	sPathRowIndex map[int]*WRS2Object
    )
    
    func init() {
    	sPathRowIndex = make(map[int]*WRS2Object)
    }
    
    // 加载 wrs2 数据
    // 这里加载的数据是经过处理的,把极地附近的给去掉了
    func loadWRS2Data(shpfile string) error {
    	shape, err := shp.Open(shpfile)
    	if err != nil {
    		return fmt.Errorf("打开文件错误:%s", err.Error())
    	}
    	defer shape.Close()
    
    	// 字段信息
    	// AREA PERIMETER PR_ PR_ID RINGS_OK RINGS_NOK PATH ROW MODE SEQUENCE WRSPR PR ACQDayL7 ACQDayL8
    	// fields := shape.Fields()
    	// fmt.Println(fields)
    	for shape.Next() {
    		n, s := shape.Shape()
    		p, ok := s.(*shp.Polygon)
    		if !ok {
    			continue
    		}
    		// 获取边界点坐标
    		coordinates := make([][]geometry.Point, p.NumParts)
    		for i := int32(0); i < p.NumParts; i += 1 {
    			var startIndex, endIndex int32
    			startIndex = p.Parts[i]
    			if i == p.NumParts-1 {
    				endIndex = int32(len(p.Points))
    			} else {
    				endIndex = p.Parts[i+1]
    			}
    
    			coordinates[i] = make([]geometry.Point, 0, endIndex-startIndex)
    			cnt := 0
    			for j := startIndex; j < endIndex; j = j + 1 {
    				var point = geometry.Point{
    					X: p.Points[j].X,
    					Y: p.Points[j].Y,
    				}
    				// 如果不是第一个或者最后一个点,判断与前一个点的距离
    				// 用于减少点数(变成四边形,虽然不准确)
    				if cnt > 0 && cnt < int(endIndex-startIndex-1) {
    					dx, dy := point.X-coordinates[i][cnt-1].X, point.Y-coordinates[i][cnt-1].Y
    					// 如果距离小于0.1度,就认为是一个点
    					if (dx*dx + dy*dy) < 0.1 {
    						continue
    					}
    				}
    				coordinates[i] = append(coordinates[i], point)
    				cnt = cnt + 1
    			}
    		}
    		// 获取路径和行号
    		var path, row int
    		path, _ = strconv.Atoi(shape.ReadAttribute(n, 6))
    		row, _ = strconv.Atoi(shape.ReadAttribute(n, 7))
    		// 插入map里面
    		var pr = path*1000 + row
    		polygon := geometry.NewPoly(coordinates[0], coordinates[1:], nil)
    		sPathRowIndex[pr] = &WRS2Object{
    			Path:     path,
    			Row:      row,
    			boundary: polygon,
    		}
    	}
    	return nil
    }
    
    func queryWRS2(path, row int) *WRS2Object {
    	p, ok := sPathRowIndex[path*1000+row]
    	if ok {
    		return p
    	}
    	return nil
    }
    
    // 简单的测试代码
    func main() {
    	loadWSR2Data("E:/WRS2_descending_0/WRS2_descending.shp")
    	fmt.Println("数据加载完成,共读取:", len(sPathRowIndex))
    
    	p := queryWSR2(13, 10)
    	if p != nil {
    		data, err := json.Marshal(p)
    		if err == nil {
    			fmt.Println(string(data))
    		} else {
    			fmt.Println(err.Error())
    		}
    	}
    }
    
  • 相关阅读:
    *ecshop 首页促销价显示倒计时
    *ecshop 限制文章帮助文章显示条数
    maven编码 gbk 的不可映射字符
    Java通过httpclient获取cookie模拟登录
    分布式系统session一致性问题
    分布式Session的几种实现方式
    httpclient 登录成功后返回的cookie值访问下一页面
    HttpClient使用GET方式通过代理服务器读取页面的例子
    HTTP请求如何带参
    JAVA的array中indexOf
  • 原文地址:https://www.cnblogs.com/oloroso/p/13700483.html
Copyright © 2011-2022 走看看