GDAL का उपयोग करके विशिष्ट अक्षांश / देशांतर स्थिति के साथ छवि बनाना?


9

मेरे पास निम्न प्रारूप में अक्षांश, देशांतर और data_val के साथ एक ASCII फ़ाइल है।

35-13.643782N, 080-57.190157W, 118.6
...

मेरे पास एक जियोफाई इमेज फाइल है, और मैं इसे आसानी से देख सकता हूं।

मैं ASCII फ़ाइल में पाए गए विशिष्ट अक्षांश / देशांतर स्थिति पर छवि पर एक "पिन" (एक डॉट / झंडा / स्टार या जो कुछ भी सबसे आसान हो सकता है) रखना चाहता हूं।

यहाँ मैं अब तक क्या करने में कामयाब रहा हूँ:

मेरी स्रोत छवि इस प्रकार है:

Driver: GTiff/GeoTIFF
Files: /tmp/Charlotte SEC 100.tif
Size is 16867, 12358
Coordinate System is:
PROJCS["Lambert Conformal Conic",
    GEOGCS["NAD83",
        DATUM["North_American_Datum_1983",
            SPHEROID["GRS 1980",6378137,298.2572221010042,
                AUTHORITY["EPSG","7019"]],
            AUTHORITY["EPSG","6269"]],
        PRIMEM["Greenwich",0],
        UNIT["degree",0.0174532925199433],
        AUTHORITY["EPSG","4269"]],
    PROJECTION["Lambert_Conformal_Conic_2SP"],
    PARAMETER["standard_parallel_1",38.66666666666666],
    PARAMETER["standard_parallel_2",33.33333333333334],
    PARAMETER["latitude_of_origin",34.11666666666667],
    PARAMETER["central_meridian",-78.75],
    PARAMETER["false_easting",0],
    PARAMETER["false_northing",0],
    UNIT["metre",1,
        AUTHORITY["EPSG","9001"]]]
Origin = (-365041.822331817995291,240536.419747152860509)
Pixel Size = (42.334586069440391,-42.334898968590878)
Metadata:
  AREA_OR_POINT=Area
  TIFFTAG_DATETIME=2016:06:24 12:46:45
  TIFFTAG_RESOLUTIONUNIT=2 (pixels/inch)
  TIFFTAG_SOFTWARE=Adobe Photoshop CS5 Windows
  TIFFTAG_XRESOLUTION=300
  TIFFTAG_YRESOLUTION=300
Image Structure Metadata:
  COMPRESSION=LZW
  INTERLEAVE=BAND
Corner Coordinates:
Upper Left  ( -365041.822,  240536.420) ( 82d48'55.43"W, 36d13' 4.92"N)
Lower Left  ( -365041.822, -282638.262) ( 82d35'10.11"W, 31d30'17.00"N)
Upper Right (  349015.641,  240536.420) ( 74d51'46.40"W, 36d13'26.16"N)
Lower Right (  349015.641, -282638.262) ( 75d 4'55.60"W, 31d30'36.99"N)
Center      (   -8013.091,  -21050.921) ( 78d50'12.11"W, 33d55'36.35"N)
Band 1 Block=16867x1 Type=Byte, ColorInterp=Palette
  Color Table (RGB with 256 entries)
    0: 255,255,255,255
...

यहाँ है कि मैं अजगर में एक साथ cobble करने में कामयाब रहा हूँ:

from osgeo import gdal, osr

src_filename = '/tmp/Charlotte SEC 100.tif'
dst_filename = '/tmp/foo.tiff'

# Opens source dataset
src_ds = gdal.Open(src_filename)
format = "GTiff"
driver = gdal.GetDriverByName(format)

# Open destination dataset
dst_ds = driver.CreateCopy(dst_filename, src_ds, 0)

# Specify raster location through geotransform array
# (upperleftx, scalex, skewx, upperlefty, skewy, scaley)
# Scale = size of one pixel in units of raster projection
# this example below assumes 100x100
gt = [-365041.822, 100, 0, 240536.420, 0, -100]

# Set location
dst_ds.SetGeoTransform(gt)

# Get raster projection
epsg = 4269            # http://spatialreference.org/ref/sr-org/lambert_conformal_conic_2sp/
srs = osr.SpatialReference()
srs.ImportFromEPSG(epsg)
dest_wkt = srs.ExportToWkt()

# Set projection
dst_ds.SetProjection(dest_wkt)

# Close files
dst_ds = None
src_ds = None

लेकिन, मैं 35-13.643782N, 080-57.190157W पर "लाल बिंदी" लगाने का तरीका समझ नहीं पाया

मुझे यहाँ कुछ नए विवरण (जीआईएस के बारे में नामकरण) सीखना होगा।


आपको जिस विषय की जांच करने की आवश्यकता हो सकती है, वह है जियोफेरेन्सिंग।
PolyGeo

धन्यवाद .. मैंने कुछ Google खोज का उपयोग करके Georeferencing शब्द का उपयोग किया। यह मददगार था। आधी लड़ाई जान रही है कि किन तकनीकी शब्दों का इस्तेमाल करना है ..
ब्रैड वॉकर

मुझे यकीन है कि मैं कुछ याद कर रहा हूं, लेकिन क्या आपने डेटा को KML या कुछ और में परिवर्तित करने पर विचार किया है?
बैरीकेटर

1
आपको अपने DD-MM.mmmmH निर्देशांक को दशमलव डिग्री में बदलने की आवश्यकता हो सकती है। आपको गोलार्ध की जानकारी W या S को पार्स करने की आवश्यकता होगी जिसका अर्थ है एक नकारात्मक मान (अंतिम चरण के रूप में ऐसा करें)। मिनटों को 60 से विभाजित किया जाना चाहिए और डिग्री भाग के साथ जोड़ा या संक्षिप्त किया जाना चाहिए।
mkennedy

जवाबों:


7

आपका gdalinfoआउटपुट दिखाता है कि आपके पास एक रंग तालिका (AKA पैलेट) के साथ एकल बैंड GeoTIFF है। मैं उस रंग तालिका में मान नहीं देख सकता, इसलिए नीचे दिए गए आदेश एकल बैंड + रंग तालिका को तीन बैंड RGB GeoTIFF में परिवर्तित करते हैं। कमांड यह भी मानती हैं कि आपकी ASCII फ़ाइल में हेडर पंक्ति है और दशमलव डिग्री में निर्देशांक हैं, यदि ऐसा नहीं होता है तो आपको अपनी फ़ाइल को संशोधित करने की आवश्यकता हो सकती है।

इनपुट:

$ cat testlonlat.csv
LON,LAT
143.798425,-15.551485
143.827437,-15.535119
143.84561,-15.530017
143.859107,-15.54819
143.812347,-15.523641
143.853581,-15.534694
143.883337,-15.537669
143.885356,-15.561687
143.887694,-15.588468

$ gdalinfo testutm.tif
Driver: GTiff/GeoTIFF
Files: testutm.tif
Size is 1102, 959
Coordinate System is:
PROJCS["WGS 84 / UTM zone 54S",
    GEOGCS["WGS 84",
        DATUM["WGS_1984",
            SPHEROID["WGS 84",6378137,298.257223563,
                AUTHORITY["EPSG","7030"]],
            AUTHORITY["EPSG","6326"]],
        PRIMEM["Greenwich",0,
            AUTHORITY["EPSG","8901"]],
        UNIT["degree",0.0174532925199433,
            AUTHORITY["EPSG","9122"]],
        AUTHORITY["EPSG","4326"]],
    PROJECTION["Transverse_Mercator"],
    PARAMETER["latitude_of_origin",0],
    PARAMETER["central_meridian",141],
    PARAMETER["scale_factor",0.9996],
    PARAMETER["false_easting",500000],
    PARAMETER["false_northing",10000000],
    UNIT["metre",1,
        AUTHORITY["EPSG","9001"]],
    AXIS["Easting",EAST],
    AXIS["Northing",NORTH],
    AUTHORITY["EPSG","32754"]]
Origin = (798741.168775000027381,8282084.855279999785125)
Pixel Size = (10.000000000000000,-10.000000000000000)
Metadata:
  AREA_OR_POINT=Area
Image Structure Metadata:
  INTERLEAVE=BAND
Corner Coordinates:
Upper Left  (  798741.169, 8282084.855) (143d47' 4.96"E, 15d31'16.22"S)
Lower Left  (  798741.169, 8272494.855) (143d47' 9.15"E, 15d36'27.98"S)
Upper Right (  809761.169, 8282084.855) (143d53'14.43"E, 15d31'11.47"S)
Lower Right (  809761.169, 8272494.855) (143d53'18.78"E, 15d36'23.20"S)
Center      (  804251.169, 8277289.855) (143d50'11.83"E, 15d33'49.74"S)
Band 1 Block=1102x7 Type=Byte, ColorInterp=Palette
  Color Table (RGB with 256 entries)
    0: 120,112,136,255
    1: 96,104,88,255
    ...
    254: 76,124,140,255
    255: 232,228,236,255

प्रक्रिया:

$ gdal_translate -expand rgb testutm.tif testutm_rgb.tif

$ ogr2ogr -f "GeoJSON" -dialect sqlite                      \
  -sql "select ST_buffer(Geometry,0.001) from testlonlat"   \
  -s_srs EPSG:4326 -t_srs EPSG:32754                        \
  /vsistdout/ CSV:testlonlat.csv -oo X_POSSIBLE_NAMES=Lon   \
  -oo Y_POSSIBLE_NAMES=Lat |  gdal_rasterize -b 1 -b 2 -b 3 \
  -burn 255 -burn 0 -burn 0 /vsistdin/ testutm_rgb.tif

अंतिम आदेश निम्न कार्य करता है:

  • एक बड़े बहुभुज के लिए लोन / लैट पॉइंट को बफ़र करता है ताकि यह बेहतर दिखाई दे (आप इसे छोड़ सकते हैं कि अगर आपको एक सिंगल पिक्सेल रंगीन ब्लैक चाहिए)
  • WGS84 लाट / लोन (EPSG: 4326) से एक ही तालमेल प्रणाली में रेखापुंज के रूप में परिवर्तित हो जाता है (EPSG: 32754 जो कि WGS 84 UTM जोन 54S है, आपका CRS अलग होगा)
  • उत्पादन बहुभुज को STDOUT में GeoJSON के रूप में लिखता है और इसे पाइप करता है gdal_rasterize
  • आरजीबी रेखापुंज बैंड 1, 2 और 3 में आरजीबी 255,0,0 जलता है

परिणाम:

यहाँ छवि विवरण दर्ज करें


3

आपने एक अच्छी शुरुआत की है। gdal.CreateCopyजियोरफेरेंसिंग का ध्यान रखेंगे, इसलिए आपको जियोट्रांसफॉर्म और प्रोजेक्शन का उपयोग करके दूसरी बार सेट करने की आवश्यकता नहीं है।

पूरी प्रक्रिया लोन / लाट कोर्ड्स को रास्टर स्पैटियल रेफरेंस के XY निर्देशांक में बदल देगी। फिर इन XY कोर्ड्स को रिवर्स जियोट्रांसफॉर्म का उपयोग करते हुए, रेखापुंज के कर्नल सूचक में बदल दिया जाएगा। कुछ पिक्सेल मान उस स्थिति में लिखे जाएंगे।

from osgeo import gdal, osr
import numpy as np

src_filename = '/tmp/Charlotte SEC 100.tif'
dst_filename = '/tmp/foo.tiff'

# Opens source dataset
src_ds = gdal.Open(src_filename)
format = "GTiff"
driver = gdal.GetDriverByName(format)

# Open destination dataset
dst_ds = driver.CreateCopy(dst_filename, src_ds, 0)

# Get raster projection
epsg = 4269         # http://spatialreference.org/ref/sr-org/lambert_conformal_conic_2sp/
srs = osr.SpatialReference()
srs.ImportFromEPSG(epsg)

# Make WGS84 lon lat coordinate system
world_sr = osr.SpatialReference()
world_sr.SetWellKnownGeogCS('WGS84')

# Transform lon lats into XY
lonlat = [[0.,30.], [20., 30.], [25., 30.]]
coord_transform = osr.CoordinateTransformation(world_sr, srs)
newpoints = coord_transform.TransformPoints(lonlat) # list of XYZ tuples

# Make Inverse Geotransform  (try:except due to gdal version differences)
try:
    success, inverse_gt = gdal.InvGeoTransform(gt)
except:
    inverse_gt = gdal.InvGeoTransform(gt)

# [Note 1] Set pixel values
marker_array_r = np.array([[255]], dtype=np.uint8)
marker_array_g = np.array([[0]], dtype=np.uint8)
marker_array_b = np.array([[0]], dtype=np.uint8)
for x,y,z in newpoints:
    pix_x = int(inverse_gt[0] + inverse_gt[1] * x + inverse_gt[2] * y)
    pix_y = int(inverse_gt[3] + inverse_gt[4] * x + inverse_gt[5] * y)
    dst_ds.GetRasterBand(1).WriteArray(marker_array_r, pix_x, pix_y)
    dst_ds.GetRasterBand(2).WriteArray(marker_array_g, pix_x, pix_y)
    dst_ds.GetRasterBand(3).WriteArray(marker_array_b, pix_x, pix_y)

# Close files
dst_ds = None
src_ds = None

नोट 1:

कमान gdal.RasterBand.WriteArray(array, xoff, yoff)ऊपरी बाएं कोने से संचालित होती है। इस उदाहरण में मैं मूल्य 255 के साथ एक 1x1 सरणी प्रदान करते हैं, तो xoffऔर yoffवास्तविक पंक्ति, देशांतर / अक्षांश पद के लिए col सूचकांक कर रहे हैं। यदि आप एक 3x3 वर्ग लिखना चाहते हैं, तो आपको समायोजित करने xoffऔर yoffघटाने की आवश्यकता है 1. आपको यह भी सुनिश्चित करना चाहिए कि सरणी डेटाटाइप्स रेखापुंज से मेल खाता है। क्योंकि आपने कहा था कि आप "लाल बिंदु" चाहते हैं, इसलिए मैं मान रहा हूं कि uint8 के तीन बैंड हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.