PageRenderTime 51ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/gdal-1.9.1-fedora/swig/java/apps/GDALProximity.java

#
Java | 542 lines | 289 code | 97 blank | 156 comment | 98 complexity | 707dcc9114dbac2f5665f09d716dc502 MD5 | raw file
Possible License(s): BSD-3-Clause, LGPL-2.0
  1. /******************************************************************************
  2. * $Id: GDALProximity.java 18104 2009-11-26 00:43:16Z ilucena $
  3. *
  4. * Project: GDAL
  5. * Purpose: Compute each pixel's proximity to a set of target pixels.
  6. * Author: Ivan Lucena, ivan.lucena@pmldnet.com,
  7. * translated from GDALProximity.cpp and gdal_proximity.py
  8. * originally written by Frank Warmerdam, warmerdam@pobox.com
  9. ******************************************************************************
  10. * Copyright (c) 2008, Frank Warmerdam
  11. *
  12. * Permission is hereby granted, free of charge, to any person obtaining a
  13. * copy of this software and associated documentation files (the "Software"),
  14. * to deal in the Software without restriction, including without limitation
  15. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  16. * and/or sell copies of the Software, and to permit persons to whom the
  17. * Software is furnished to do so, subject to the following conditions:
  18. *
  19. * The above copyright notice and this permission notice shall be included
  20. * in all copies or substantial portions of the Software.
  21. *
  22. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  23. * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  24. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  25. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  26. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  27. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  28. * DEALINGS IN THE SOFTWARE.
  29. ****************************************************************************/
  30. import org.gdal.gdal.Band;
  31. import org.gdal.gdal.Dataset;
  32. import org.gdal.gdal.Driver;
  33. import org.gdal.gdal.gdal;
  34. import org.gdal.gdalconst.gdalconstConstants;
  35. /**
  36. Compute the proximity of all pixels in the image to a set of pixels in the source image.
  37. This function attempts to compute the proximity of all pixels in
  38. the image to a set of pixels in the source image. The following
  39. options are used to define the behavior of the function. By
  40. default all non-zero pixels in hSrcBand will be considered the
  41. "target", and all proximities will be computed in pixels. Note
  42. that target pixels are set to the value corresponding to a distance
  43. of zero.
  44. The progress function args may be NULL or a valid progress reporting function
  45. such as GDALTermProgress/NULL.
  46. Options:
  47. VALUES=n[,n]*
  48. A list of target pixel values to measure the distance from. If this
  49. option is not provided proximity will be computed from non-zero
  50. pixel values. Currently pixel values are internally processed as
  51. integers.
  52. DISTUNITS=[PIXEL]/GEO
  53. Indicates whether distances will be computed in pixel units or
  54. in georeferenced units. The default is pixel units. This also
  55. determines the interpretation of MAXDIST.
  56. MAXDIST=n
  57. The maximum distance to search. Proximity distances greater than
  58. this value will not be computed. Instead output pixels will be
  59. set to a nodata value.
  60. NODATA=n
  61. The NODATA value to use on the output band for pixels that are
  62. beyond MAXDIST. If not provided, the hProximityBand will be
  63. queried for a nodata value. If one is not found, 65535 will be used.
  64. FIXED_BUF_VAL=n
  65. If this option is set, all pixels within the MAXDIST threadhold are
  66. set to this fixed value instead of to a proximity distance.
  67. */
  68. public class GDALProximity {
  69. public static void Usage() {
  70. System.out.println("Usage: Proximity srcfile dstfile [-srcband n] [-dstband n]");
  71. System.out.println(" [-of format] [-co name=value]*");
  72. System.out.println(" [-ot Byte/Int16/Int32/Float32/etc]");
  73. System.out.println(" [-values n,n,n] [-distunits PIXEL/GEO]");
  74. System.out.println(" [-maxdist n] [-nodata n] [-fixed-buf-val n]");
  75. System.exit(1);
  76. }
  77. public static void main(String[] args) {
  78. String SourceFilename = null;
  79. String OutputFilename = null;
  80. /*
  81. * Parse arguments
  82. */
  83. int SourceBand = 1;
  84. int DestinyBand = 1;
  85. float MaxDistance = -1.0F;
  86. boolean GeoUnits = false;
  87. float Nodata = 0.0F;
  88. float BufferValue = 0.0F;
  89. boolean hasBufferValue = false;
  90. String OutputFormat = "GTiff";
  91. String OutputType = "Float32";
  92. int TargetValues[] = new int[0];
  93. float DistMult = 1.0F;
  94. String Options = "";
  95. for (int i = 0; i < args.length; i++) {
  96. if (args[i].equals("-of")) {
  97. i++;
  98. OutputFormat = args[i];
  99. } else if (args[i].equals("-ot")) {
  100. i++;
  101. OutputType = args[i];
  102. } else if (args[i].equals("-maxdist")) {
  103. i++;
  104. MaxDistance = Float.parseFloat(args[i]);
  105. } else if (args[i].equals("-srcband")) {
  106. i++;
  107. SourceBand = Integer.parseInt(args[i]);
  108. } else if (args[i].equals("-dstband")) {
  109. i++;
  110. DestinyBand = Integer.parseInt(args[i]);
  111. } else if (args[i].equals("-distunits")) {
  112. i++;
  113. if( args[i].equals("geo") ) {
  114. GeoUnits = true;
  115. } else if ( args[i].equals("pixel") ) {
  116. GeoUnits = false;
  117. } else {
  118. Usage();
  119. }
  120. } else if (args[i].equals("-nodata")) {
  121. i++;
  122. Nodata = Float.parseFloat(args[i]);
  123. } else if (args[i].equals("-co")) {
  124. i++;
  125. Options += args[i] + ';';
  126. } else if (args[i].equals("-values")) {
  127. i++;
  128. String valStr[] = args[i].split(",");
  129. TargetValues = new int[valStr.length];
  130. for (int j = 0; j < valStr.length; j++) {
  131. TargetValues[j] = Integer.parseInt(valStr[j].trim());
  132. }
  133. } else if (args[i].equals("-fixed-buf-val")) {
  134. i++;
  135. BufferValue = Float.parseFloat(args[i]);
  136. hasBufferValue = true;
  137. } else if (SourceFilename == null) {
  138. SourceFilename = args[i];
  139. } else if (OutputFilename == null) {
  140. OutputFilename = args[i];
  141. } else {
  142. Usage();
  143. }
  144. }
  145. if (SourceFilename == null) {
  146. Usage();
  147. }
  148. gdal.AllRegister();
  149. /*
  150. * Open Input
  151. */
  152. Dataset SourceDataset = null;
  153. Dataset WorkProximityDataset = null;
  154. Driver WorkProximityDriver = null;
  155. SourceDataset = gdal.Open(SourceFilename, gdalconstConstants.GA_ReadOnly);
  156. if (SourceDataset == null) {
  157. System.err.println("GDALOpen failed - " + gdal.GetLastErrorNo());
  158. System.err.println(gdal.GetLastErrorMsg());
  159. System.exit(1);
  160. }
  161. /*
  162. * Open Output
  163. */
  164. WorkProximityDriver = gdal.IdentifyDriver(OutputFilename);
  165. if (WorkProximityDriver != null) {
  166. WorkProximityDataset = gdal.Open(OutputFilename, gdalconstConstants.GA_Update);
  167. if (WorkProximityDataset == null) {
  168. System.err.println("GDALOpen failed - " + gdal.GetLastErrorNo());
  169. System.err.println(gdal.GetLastErrorMsg());
  170. System.exit(1);
  171. }
  172. } else {
  173. /*
  174. * Create a new output dataset
  175. */
  176. WorkProximityDriver = gdal.GetDriverByName(OutputFormat);
  177. WorkProximityDataset = WorkProximityDriver.Create(OutputFilename,
  178. SourceDataset.getRasterXSize(), SourceDataset.getRasterYSize(),
  179. SourceDataset.getRasterCount(), gdal.GetDataTypeByName(OutputType),
  180. Options.split(";"));
  181. WorkProximityDataset.SetGeoTransform(SourceDataset.GetGeoTransform());
  182. WorkProximityDataset.SetProjection(SourceDataset.GetProjectionRef());
  183. }
  184. if (WorkProximityDataset == null) {
  185. System.err.println("GDALOpen failed - " + gdal.GetLastErrorNo());
  186. System.err.println(gdal.GetLastErrorMsg());
  187. System.exit(1);
  188. }
  189. /*
  190. * Are we using pixels or georeferenced coordinates for distances?
  191. */
  192. if( GeoUnits ) {
  193. double geoTransform[] = SourceDataset.GetGeoTransform();
  194. if( Math.abs(geoTransform[1]) != Math.abs(geoTransform[5])) {
  195. System.err.println("Pixels not square, distances will be inaccurate.");
  196. }
  197. DistMult = (float) Math.abs(geoTransform[1]);
  198. }
  199. long startTime = System.currentTimeMillis();
  200. /*
  201. * Calculate Proximity
  202. */
  203. Run(SourceDataset.GetRasterBand(SourceBand),
  204. WorkProximityDataset.GetRasterBand(DestinyBand),
  205. DistMult,
  206. MaxDistance,
  207. Nodata,
  208. hasBufferValue,
  209. BufferValue,
  210. TargetValues);
  211. /*
  212. * Clean up
  213. */
  214. long stopTime = System.currentTimeMillis();
  215. SourceDataset.delete();
  216. WorkProximityDataset.delete();
  217. gdal.GDALDestroyDriverManager();
  218. System.out.println("Done in " + ((double) (stopTime - startTime) / 1000.0) + " seconds");
  219. }
  220. public static void Run(Band SrcBand, Band ProximityBand,
  221. float DistMult, float MaxDistance, float NoData,
  222. boolean HasBufferValue, float BufferValue, int TargetValues[]) {
  223. /*
  224. * What is our maxdist value?
  225. */
  226. if (MaxDistance == -1.0F) {
  227. MaxDistance = SrcBand.GetXSize() + SrcBand.GetYSize();
  228. }
  229. /*
  230. * Create working band
  231. */
  232. Band WorkProximityBand = ProximityBand;
  233. Dataset WorkProximityDS = null;
  234. int ProxType = ProximityBand.getDataType();
  235. String tempFilename = null;
  236. if (ProxType == gdalconstConstants.GDT_Byte
  237. || ProxType == gdalconstConstants.GDT_UInt16
  238. || ProxType == gdalconstConstants.GDT_UInt32) {
  239. tempFilename = "/vsimem/proximity_" + String.valueOf(System.currentTimeMillis()) + ".tif";
  240. WorkProximityDS = gdal.GetDriverByName("GTiff").Create(tempFilename,
  241. ProximityBand.getXSize(), ProximityBand.getYSize(), 1,
  242. gdalconstConstants.GDT_Float32);
  243. WorkProximityBand = WorkProximityDS.GetRasterBand(1);
  244. }
  245. int xSize = WorkProximityBand.getXSize();
  246. int ySize = WorkProximityBand.getYSize();
  247. /*
  248. * Allocate buffers
  249. */
  250. short nearXBuffer[] = new short[xSize];
  251. short nearYBuffer[] = new short[xSize];
  252. int scanline[] = new int[xSize];
  253. float proximityBuffer[] = new float[xSize];
  254. /*
  255. * Loop from top to bottom of the image
  256. */
  257. for (int i = 0; i < xSize; i++) {
  258. nearXBuffer[i] = -1;
  259. nearYBuffer[i] = -1;
  260. }
  261. for (int iLine = 0; iLine < ySize; iLine++) {
  262. SrcBand.ReadRaster(0, iLine, xSize, 1, xSize, 1,
  263. gdalconstConstants.GDT_Int32, scanline);
  264. for (int i = 0; i < xSize; i++) {
  265. proximityBuffer[i] = -1F;
  266. }
  267. /*
  268. * Left to Right
  269. */
  270. ProcessProximityLine(scanline, nearXBuffer, nearYBuffer,
  271. true, iLine, xSize, MaxDistance, proximityBuffer,
  272. TargetValues);
  273. /*
  274. * Right to Left
  275. */
  276. ProcessProximityLine(scanline, nearXBuffer, nearYBuffer,
  277. false, iLine, xSize, MaxDistance, proximityBuffer,
  278. TargetValues);
  279. /*
  280. * Write to Proximity Band
  281. */
  282. WorkProximityBand.WriteRaster(0, iLine, xSize, 1, xSize, 1,
  283. gdalconstConstants.GDT_Float32, proximityBuffer);
  284. }
  285. /*
  286. * Loop from bottom to top of the image
  287. */
  288. for (int i = 0; i < xSize; i++) {
  289. nearXBuffer[i] = -1;
  290. nearYBuffer[i] = -1;
  291. }
  292. for (int iLine = ySize - 1; iLine >= 0; iLine--) {
  293. WorkProximityBand.ReadRaster(0, iLine, xSize, 1, xSize, 1,
  294. gdalconstConstants.GDT_Float32, proximityBuffer);
  295. SrcBand.ReadRaster(0, iLine, xSize, 1, xSize, 1,
  296. gdalconstConstants.GDT_Int32, scanline);
  297. /*
  298. * Right to Left
  299. */
  300. ProcessProximityLine(scanline, nearXBuffer, nearYBuffer,
  301. false, iLine, xSize, MaxDistance, proximityBuffer,
  302. TargetValues);
  303. /*
  304. * Left to Right
  305. */
  306. ProcessProximityLine(scanline, nearXBuffer, nearYBuffer,
  307. true, iLine, xSize, MaxDistance, proximityBuffer,
  308. TargetValues);
  309. /*
  310. * Final post processing of distances.
  311. */
  312. for (int i = 0; i < xSize; i++) {
  313. if (proximityBuffer[i] < 0.0F) {
  314. proximityBuffer[i] = NoData;
  315. } else if (proximityBuffer[i] > 0.0F) {
  316. if (HasBufferValue) {
  317. proximityBuffer[i] = BufferValue;
  318. } else {
  319. proximityBuffer[i] = DistMult * proximityBuffer[i];
  320. }
  321. }
  322. }
  323. /*
  324. * Write to Proximity Band
  325. */
  326. ProximityBand.WriteRaster(0, iLine, xSize, 1, xSize, 1,
  327. gdalconstConstants.GDT_Float32, proximityBuffer);
  328. }
  329. ProximityBand.FlushCache();
  330. /*
  331. * Delete temporary file
  332. */
  333. if (WorkProximityDS != null) {
  334. WorkProximityDS.delete();
  335. /*
  336. * Delete virtual file from memory
  337. */
  338. gdal.Unlink(tempFilename);
  339. }
  340. }
  341. public static void ProcessProximityLine(int[] scanlineArray,
  342. short[] nearXArray, short[] nearYArray, boolean Forward,
  343. int iLine, int XSize, float MaxDist, float[] proximityArray,
  344. int TargetValues[]) {
  345. int iStart, iEnd, iStep, iPixel;
  346. if (Forward) {
  347. iStart = 0;
  348. iEnd = XSize;
  349. iStep = 1;
  350. } else {
  351. iStart = XSize - 1;
  352. iEnd = -1;
  353. iStep = -1;
  354. }
  355. for (iPixel = iStart; iPixel != iEnd; iPixel += iStep) {
  356. /*
  357. * Is the current pixel a target pixel?
  358. */
  359. boolean isATarger = false;
  360. if( TargetValues.length == 0) {
  361. isATarger = scanlineArray[iPixel] != 0.0F;
  362. } else {
  363. for( int i = 0; i < TargetValues.length; i++) {
  364. if( scanlineArray[iPixel] == TargetValues[i] ) {
  365. isATarger = true;
  366. break;
  367. }
  368. }
  369. }
  370. if (isATarger) {
  371. proximityArray[iPixel] = 0.0F;
  372. nearXArray[iPixel] = (short) iPixel;
  373. nearYArray[iPixel] = (short) iLine;
  374. continue;
  375. }
  376. float NearDistSq = (float) Math.max((double) MaxDist, (double) XSize);
  377. NearDistSq = NearDistSq * NearDistSq * 2.0F;
  378. float DistSq = 0.0F;
  379. /*
  380. * Are we near(er) to to the closest target to the above (below)
  381. * pixel?
  382. */
  383. if (nearXArray[iPixel] != -1) {
  384. DistSq = (nearXArray[iPixel] - iPixel) * (nearXArray[iPixel] - iPixel)
  385. + (nearYArray[iPixel] - iLine) * (nearYArray[iPixel] - iLine);
  386. if (DistSq < NearDistSq) {
  387. NearDistSq = DistSq;
  388. } else {
  389. nearXArray[iPixel] = (short) -1;
  390. nearYArray[iPixel] = (short) -1;
  391. }
  392. }
  393. /*
  394. * Are we near(er) to to the closest target to the left (right)
  395. * pixel?
  396. */
  397. int iLast = iPixel - iStep;
  398. if (iPixel != iStart && nearXArray[iLast] != -1) {
  399. DistSq = (nearXArray[iLast] - iPixel) * (nearXArray[iLast] - iPixel)
  400. + (nearYArray[iLast] - iLine) * (nearYArray[iLast] - iLine);
  401. if (DistSq < NearDistSq) {
  402. NearDistSq = DistSq;
  403. nearXArray[iPixel] = nearXArray[iLast];
  404. nearYArray[iPixel] = nearYArray[iLast];
  405. }
  406. }
  407. /*
  408. * Are we near(er) to the closest target to the top right (bottom
  409. * left) pixel?
  410. */
  411. int iTarget = iPixel + iStep;
  412. if (iTarget != iEnd && nearXArray[iTarget] != -1) {
  413. DistSq = (nearXArray[iTarget] - iPixel) * (nearXArray[iTarget] - iPixel)
  414. + (nearYArray[iTarget] - iLine) * (nearYArray[iTarget] - iLine);
  415. if (DistSq < NearDistSq) {
  416. NearDistSq = DistSq;
  417. nearXArray[iPixel] = nearXArray[iTarget];
  418. nearYArray[iPixel] = nearYArray[iTarget];
  419. }
  420. }
  421. /*
  422. * Update our proximity value.
  423. */
  424. if (nearXArray[iPixel] != -1
  425. && NearDistSq <= (MaxDist * MaxDist)
  426. && (proximityArray[iPixel] < 0
  427. || NearDistSq < (proximityArray[iPixel] * proximityArray[iPixel]))) {
  428. proximityArray[iPixel] = (float) Math.sqrt((double) NearDistSq);
  429. }
  430. }
  431. }
  432. }