记录常用GDAL命令
记录下自己在项目中用过的GDAL命令,方便自己查看。
文章目录
一、空间数据信息查看
1.1 获取参考坐标系
/**
* 获取参考坐标系
* @param geoPath
* @return
*/
public static String getEPSG(String geoPath) {
String cmd = String.format("gdalsrsinfo -e %s",geoPath);
InputStream is = null;
try {
Runtime rm = Runtime.getRuntime();
Process exec = rm.exec(cmd);
exec.waitFor();
is = exec.getInputStream();
String result = IOUtils.toString(is, "UTF-8");
for (String s : result.split("\n")) {
if (s.startsWith("EPSG")) {
return s;
}
}
} catch (InterruptedException | IOException e) {
e.printStackTrace();
return null;
}finally {
IOUtils.closeQuietly(is);
}
return null;
}
二、空间数据格式转换相关
2.1、GeoJson、gdb(注意geoDataPath的路径)转SHP
String.format("ogr2ogr -lco encoding=UTF-8 -f \"ESRI Shapefile\" %s %s",shpPath, geoDataPath);
2.2、dwg或dxf转GeoJson
由于dwg无法直接读取,具体流程为先用ODAFileConverter把dwg转成dxf,再用gdal把dxf转成shp,再把shp转成GeoJson。其中dxf转shp的时候要分成{“POINT”,“LINESTRING”,“POLYGON”}来转,转完了在判断一下shp中有没有数据,将没有数据的shp删掉。
/**
* 先把dwg转成dxf,再把dxf转成shp
* @param OdaPath 第三方处理dwg软件地址 D:\ODA\ODAFileConverter_title 22.3.0\ODAFileConverter.exe
* @param inputPath 输入文件地址
* @param resPath 输出文件地址
*/
public static void dwgToShp(String OdaPath,String inputPath,String resPath){
String[] COMMAND = {OdaPath, inputPath, resPath, "ACAD10", "DXF", "0", "0"};
try {
File resFile = new File(resPath);
if (!resFile.exists()) {
resFile.mkdirs();
}
ProcessBuilder pb = new ProcessBuilder(COMMAND).redirectErrorStream(true);
pb.start().waitFor();
Arrays.stream(Objects.requireNonNull(resFile.listFiles()))
.filter(e->e.getName().endsWith(".dxf"))
.forEach(e->dxfToShp(e.getPath(), resPath));
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* dxf转shp(注意:复杂dxf需要转成三个不同数据类型的shp,然后再排除掉空或则数据异常的shp)
* @param filePath
* @param resPath
*/
public static void dxfToShp(String filePath,String resPath){
String[] types = {"POINT","LINESTRING","POLYGON"};
try {
String name = new File(filePath).getName().split("\\.")[0];
for (String geometryName : types) {
String fileName = name + "_" + geometryName;
String shpFilePath = resPath + File.separator + fileName+".shp";
//唉,分不同的类型转
String command = "ogr2ogr -where \"OGR_GEOMETRY='"+geometryName+"'\" -lco encoding=UTF-8 " +
"-f \"ESRI Shapefile\" "+ shpFilePath +" " + filePath;
Runtime rm = Runtime.getRuntime();
Process exec = rm.exec(command);
exec.waitFor();
}
}catch (Exception e){
e.printStackTrace();
}finally {
checkShp(resPath);
}
}
/**
* 排除异常shp
* @param resPath
*/
public static void checkShp(String resPath){
try {
File[] files = new File(resPath).listFiles();
for (File file : files) {
if(file.getName().endsWith(".shp")){
String cmd = String.format("ogrinfo -ro -al -so %s", file.getPath());
Runtime rm = Runtime.getRuntime();
Process exec = rm.exec(cmd);
exec.waitFor();
InputStream is = exec.getInputStream();
String res = IOUtils.toString(is, "UTF-8");
//得到layerCount
String[] strings = StringUtils.substringsBetween(res, "Feature Count:", "Extent:");
if (strings.length > 0) {
int layerCount = Integer.parseInt(strings[0].replaceAll("\\s+", ""));
if(layerCount <= 0){
file.delete();
}
}
}
}
}catch (Exception e){
e.printStackTrace();
}
}
三、按掩膜提取
3.1、按geoJson提取栅格
参数名称 | 参数解释 |
---|---|
-crop_to_cutline | 提取后的栅格只包含相交部分 |
-cutline | geoJson文件地址 |
String.format("gdalwarp -crop_to_cutline " +
"-t_srs %s " +
"-cutline %s " +
"-overwrite %s %s", epsg, geoJsonPath,
map.get("sourcesPath"), resTifPath);
四、获取外接矩形
4.1 根据栅格像元值生成GeoJson边界
/**
* 根据栅格文件的有效值生成GeoJSON边界
*
* @param o
* @return
*/
public Map<String, Object> rasterToVector(HashMap<String, String> o) {
Map<String, Object> resMap = new HashMap<>();
String ascPath = o.get("ascPath");
File file = new File(ascPath);
String resTifPath = file.getParent() + File.separator + "tmp_" + file.getName();
String geoJsonPath = file.getParent() + File.separator + UUID.randomUUID().toString().replaceAll("-", "") + ".geojson";
try {
//通过gdalinfo获取栅格noDataValue
String exec = CommonUtils.exec("gdalinfo -json " + ascPath);
JSONObject jsonObject = JSON.parseObject(exec);
List<Map<String, Object>> bands = (List<Map<String, Object>>) jsonObject.get("bands");
Map<String, Object> map = bands.get(0);
String noDataValue = map.get("noDataValue").toString();
//将栅格的像元值设置成一样,不然最后的结果是一块一块的,并将asc输出为GTiff方便后面操作
String format = String.format("gdal_calc.py --format='GTiff' --calc='numpy.where(A != %s , %s, %s)' -A %s --outfile='%s'",
noDataValue, Double.parseDouble(noDataValue) + 1,noDataValue, ascPath, resTifPath);
System.out.println(format);
//在Linux环境下必须加这个,不然用不了
String[] cmd = {"/bin/sh", "-c", format};
Process exec1 = Runtime.getRuntime().exec(cmd);
exec1.waitFor();
//根据像元值生成边界GeoJson
String format2 = String.format("gdal_polygonize.py -f geojson %s %s", resTifPath, geoJsonPath);
System.out.println(format2);
String[] cmd2 = {"/bin/sh", "-c", format2};
Process exec2 = Runtime.getRuntime().exec(cmd2);
exec2.waitFor();
String s = IOUtils.toString(new FileInputStream(geoJsonPath), StandardCharsets.UTF_8);
resMap.put("res", JSON.parseObject(s));
return resMap;
} catch (Exception e) {
e.printStackTrace();
resMap.put("res", e.getMessage());
return resMap;
} finally {
new File(resTifPath).delete();
new File(geoJsonPath).delete();
}
}