PostGIS में x- दिशा (पूर्व-पश्चिम दिशा) में बहुभुज के भीतर अधिकतम दूरी की गणना?


13

मैं पूर्व-पश्चिम दिशा में एक बहुभुज जैसे एक झील की अधिकतम चौड़ाई में दिलचस्पी रखता हूं। बाउंडिंग बॉक्स केवल साधारण बहुभुजों में ही मदद करेंगे, लेकिन जटिल अवतल बहुभुज में नहीं।


3
मैं पोस्टगिस कार्यक्षमता से परिचित नहीं हूं। हालाँकि, एक बाउंडिंग बॉक्स टूल हो सकता है। बाउंडिंग बॉक्स की चौड़ाई ईडब्ल्यू दिशा में अधिकतम दूरी होगी।
Fezter

4
@ फ़ाइज़र ठीक नहीं है: एक साधारण जटिल बहुभुज के लिए भी एक प्रतिरूप, SW से NE तक फैली एक पतली छंद है। इसकी अधिकतम पूर्व-पश्चिम चौड़ाई इसके बाउंडिंग बॉक्स की चौड़ाई का एक छोटा सा अंश हो सकती है।
व्हिबर

1
मैंने इस कार्य और इस प्रस्तावों के आधार पर इसकी उपयोगिता बनाई है । यह बहुभुज की अधिकतम या न्यूनतम चौड़ाई की गणना करने में सक्षम है। वर्तमान में यह एक shp-files के साथ काम करता है, लेकिन आप इसे PostGIS के साथ काम करने के लिए फिर से लिख सकते हैं या बस कुछ समय तक प्रतीक्षा कर सकते हैं जब तक कि यह QGIS प्लगइन में विकसित न हो जाए जो PostGIS के साथ भी काम करेगा। विस्तृत विवरण और डाउनलोड लिंक यहाँ
SS_Rebelious

जवाबों:


16

इस संभावना को किसी भी जीआईएस प्लेटफॉर्म में कुछ स्क्रिप्टिंग की आवश्यकता होती है।

सबसे कुशल विधि (asymptotically) एक वर्टिकल लाइन स्वीप है: इसमें किनारों को उनके न्यूनतम y- निर्देशांक द्वारा छांटने और फिर किनारों को नीचे (न्यूनतम y) से ऊपर (अधिकतम y) तक संसाधित करने की आवश्यकता होती है, O (e * log) के लिए ई)) एल्गोरिथ्म जब किनारों शामिल हैं।

प्रक्रिया, हालांकि सरल है, सभी मामलों में सही पाने के लिए आश्चर्यजनक रूप से मुश्किल है। बहुभुज गंदे हो सकते हैं: उनके पास झूलने, स्लिवर्स, छेद हो सकते हैं, डिस्कनेक्ट हो सकते हैं, अनुलंब रेखाएं, सीधी रेखाओं के साथ रन होते हैं, और दो आसन्न घटकों के बीच असमान सीमाएं होती हैं। यहाँ इन विशेषताओं में से कई का प्रदर्शन एक उदाहरण है (और अधिक):

एक बहुभुज

हम विशेष रूप से बहुभुज के बंद होने के भीतर अधिकतम लंबाई वाले क्षैतिज खंड (ओं) की तलाश करेंगे । उदाहरण के लिए, यह x = 20 और x = 40 के बीच के छिद्र को x = 10 और x = 25 के बीच के छिद्र से निकालता है। यह दिखाने के लिए सीधा है कि अधिकतम लंबाई वाले क्षैतिज खंडों में से कम से कम एक शीर्ष पर स्थित है। (यदि कोई कोने को काटते हुए समाधान नहीं हैं, तो वे समाधान द्वारा ऊपर और नीचे बंधे हुए कुछ समांतर चतुर्भुज के आंतरिक भाग में स्थित होंगे, जो कम से कम एक शीर्ष पर प्रतिच्छेद करते हैं । यह हमें सभी समाधान खोजने का साधन देता है ।)

तदनुसार, लाइन स्वीप को सबसे निचले कोने से शुरू करना चाहिए और फिर अपने शीर्ष पर रुकने के लिए ऊपर (यानी उच्च y मान की ओर) बढ़ना चाहिए। प्रत्येक पड़ाव में, हम किसी भी नए किनारों को उस ऊँचाई से ऊपर की ओर निकलते हुए पाते हैं; उस ऊंचाई पर नीचे से समाप्त होने वाले किसी भी किनारे को समाप्त करना (यह महत्वपूर्ण विचारों में से एक है: यह एल्गोरिथ्म को सरल करता है और संभावित प्रसंस्करण के आधे को समाप्त करता है); और सावधानी से किसी भी किनारों को पूरी तरह से एक निरंतर ऊंचाई (क्षैतिज किनारों) पर लेटने की प्रक्रिया करें।

उदाहरण के लिए, उस स्थिति पर विचार करें जब y = 10 का स्तर पहुंचता है। बाएं से दाएं, हम निम्नलिखित किनारों को पाते हैं:

      x.min x.max y.min y.max
 [1,]    10     0     0    30
 [2,]    10    24    10    20
 [3,]    20    24    10    20
 [4,]    20    40    10    10
 [5,]    40    20    10    10
 [6,]    60     0     5    30
 [7,]    60    60     5    30
 [8,]    60    70     5    20
 [9,]    60    70     5    15
[10,]    90   100    10    40

इस तालिका में, (x.min, y.min) किनारे के निचले छोर के निर्देशांक हैं और (x.max, y.max) इसके ऊपरी समापन बिंदु के निर्देशांक हैं। इस स्तर (y = 10) पर, पहले किनारे को इसके आंतरिक हिस्से के भीतर इंटरसेप्ट किया गया है, दूसरे को इसके तल पर इंटरसेप्ट किया गया है, और इसी तरह। इस स्तर पर समाप्त होने वाले कुछ किनारों, जैसे (10,0) से (10,10), सूची में शामिल नहीं हैं।

यह निर्धारित करने के लिए कि आंतरिक बिंदु कहां हैं और बाहरी वाले हैं, अत्यधिक बाएं से शुरू होने की कल्पना करें - जो बहुभुज के बाहर है, निश्चित रूप से - और क्षैतिज रूप से दाईं ओर बढ़ रहा है। हर बार जब हम एक किनारे को पार करते हैं जो क्षैतिज नहीं होता है , तो हम वैकल्पिक रूप से बाहरी से आंतरिक और वापस स्विच करते हैं। (यह एक और महत्वपूर्ण विचार है।) हालांकि, किसी भी क्षैतिज किनारे के भीतर सभी बिंदु बहुभुज के अंदर होने के लिए निर्धारित किए जाते हैं, चाहे कोई भी हो। (बहुभुज के बंद होने में हमेशा इसके किनारे शामिल होते हैं।)

उदाहरण को जारी रखते हुए, यहां x-निर्देशांक की क्रमबद्ध सूची है जहां गैर-क्षैतिज किनारों की शुरुआत होती है और y = 10 रेखा को पार करते हैं:

x.array    6.7 10 20 48 60 63.3 65 90
interior     1  0  1  0  1    0  1  0

(ध्यान दें कि x = 40 इस सूची में नहीं है।) interiorसरणी के मान आंतरिक खंडों के बाएं छोरों को चिह्नित करते हैं: 1 एक आंतरिक अंतराल, 0 एक बाहरी अंतराल नामित करता है। इस प्रकार, पहला 1 x = 6.7 से x = 10 तक अंतराल को इंगित करता है बहुभुज के अंदर। अगला 0 x = 10 से x = 20 के अंतराल को बहुभुज के बाहर दर्शाता है । और इसलिए यह आगे बढ़ता है: सरणी बहुभुज के अंदर चार अलग-अलग अंतराल की पहचान करती है।

इनमें से कुछ अंतराल, जैसे कि x = 60 से x = 63.3 तक, किसी भी कोने को नहीं काटते हैं: y = 10 के साथ सभी कोने के x- निर्देशांक के खिलाफ एक त्वरित जांच ऐसे अंतराल को समाप्त कर देती है।

स्कैन के दौरान हम इन अंतरालों की लंबाई की निगरानी कर सकते हैं, जो अब तक पाए गए अधिकतम-लंबाई अंतराल (ओं) से संबंधित डेटा को बनाए रखते हैं।

इस दृष्टिकोण के कुछ निहितार्थों पर ध्यान दें। एक "वी" आकार का शीर्ष, जब सामना किया जाता है, तो दो किनारों की उत्पत्ति होती है। इसलिए इसे पार करते समय दो स्विच होते हैं। वे स्विच रद्द हो जाते हैं। किसी भी उल्टा "वी" को भी संसाधित नहीं किया जाता है, क्योंकि इसके दोनों किनारों को बाएं से दाएं स्कैन शुरू करने से पहले समाप्त कर दिया जाता है। दोनों ही मामलों में, इस तरह के एक शीर्ष क्षैतिज खंड को बंद नहीं करता है।

दो से अधिक किनारों को एक शीर्ष साझा कर सकते हैं: यह (10,0), (60,5), (25, 20), और - (हालांकि, 20,10) और - (40 पर बताना कठिन है) , 10)। (ऐसा इसलिए है क्योंकि दंगल (20,10) -> (40,10) -> (40,0) -> (40, -50) -> (40, 10) -> (20) 10)। ध्यान दें कि कैसे (40,0) पर शीर्ष भी एक और किनारे के इंटीरियर में है ... यह बुरा है।) यह एल्गोरिथ्म उन स्थितियों को बस ठीक से संभालता है।

एक मुश्किल स्थिति को बहुत नीचे चित्रित किया गया है: गैर-क्षैतिज खंडों के एक्स-निर्देशांक हैं

30, 50

यह एक्स = 30 के बाईं ओर सब कुछ बाहरी माना जाता है, सब कुछ 30 और 50 के बीच आंतरिक होने के लिए, और 50 के बाद सब कुछ फिर से बाहरी होने के लिए। इस एल्गोरिथ्म में x = 40 पर वर्टेक्स को कभी भी नहीं माना जाता है।

यहाँ बहुभुज स्कैन के अंत में कैसा दिखता है। मैं सभी शीर्ष-युक्त आंतरिक अंतराल को ग्रे में दिखाता हूं, लाल रंग में किसी भी अधिकतम-लंबाई के अंतराल और उनके y- निर्देशांक के अनुसार कोने को रंग देता हूं। अधिकतम अंतराल 64 इकाइयों लंबा है।

स्कैन के बाद

इसमें शामिल केवल ज्यामितीय गणनाएं होती हैं, जहां किनारों को क्षैतिज रेखाओं को काटते हैं: यह एक सरल रैखिक प्रक्षेप है। गणना यह भी निर्धारित करने के लिए आवश्यक है कि कौन से आंतरिक खंडों में कोने हैं: ये समानता निर्धारण हैं, आसानी से असमानताओं के एक जोड़े के साथ गणना की जाती है। यह सादगी एल्गोरिदम को पूर्णांक और फ्लोटिंग पॉइंट समन्वय अभ्यावेदन दोनों के लिए मजबूत और उपयुक्त बनाती है।

यदि निर्देशांक भौगोलिक हैं , तो क्षैतिज रेखाएं अक्षांश के हलकों पर वास्तव में हैं। उनकी लंबाई की गणना करना मुश्किल नहीं है: बस उनके यूक्लिडियन लंबाई को उनके अक्षांश (एक गोलाकार मॉडल में) के कोसाइन से गुणा करें। इसलिए यह एल्गोरिदम भौगोलिक निर्देशांक के लिए अच्छी तरह से adapts। (+ -180 मेरिडियन कुएं के चारों ओर आवरण को संभालने के लिए, किसी को पहले दक्षिणी ध्रुव से उत्तरी ध्रुव तक एक वक्र खोजने की आवश्यकता हो सकती है जो बहुभुज से नहीं गुजरता है। सभी एक्स-निर्देशांक को क्षैतिज विस्थापन के रूप में फिर से व्यक्त करने के बाद। वक्र, इस एल्गोरिथ्म सही ढंग से अधिकतम क्षैतिज खंड मिल जाएगा।)


Rगणना करने और चित्र बनाने के लिए लागू कोड निम्नलिखित है ।

#
# Plotting functions.
#
points.polygon <- function(p, ...) {
  points(p$v, ...)
}
plot.polygon <- function(p, ...) {
  apply(p$e, 1, function(e) lines(matrix(e[c("x.min", "x.max", "y.min", "y.max")], ncol=2), ...))
}
expand <- function(bb, e=1) {
  a <- matrix(c(e, 0, 0, e), ncol=2)
  origin <- apply(bb, 2, mean)
  delta <-  origin %*% a - origin
  t(apply(bb %*% a, 1, function(x) x - delta))
}
#
# Convert polygon to a better data structure.
#
# A polygon class has three attributes:
#   v is an array of vertex coordinates "x" and "y" sorted by increasing y;
#   e is an array of edges from (x.min, y.min) to (x.max, y.max) with y.max >= y.min, sorted by y.min;
#   bb is its rectangular extent (x0,y0), (x1,y1).
#
as.polygon <- function(p) {
  #
  # p is a list of linestrings, each represented as a sequence of 2-vectors 
  # with coordinates in columns "x" and "y". 
  #
  f <- function(p) {
    g <- function(i) {
      v <- p[(i-1):i, ]
      v[order(v[, "y"]), ]
    }
    sapply(2:nrow(p), g)
  }
  vertices <- do.call(rbind, p)
  edges <- t(do.call(cbind, lapply(p, f)))
  colnames(edges) <- c("x.min", "x.max", "y.min", "y.max")
  #
  # Sort by y.min.
  #
  vertices <- vertices[order(vertices[, "y"]), ]
  vertices <- vertices[!duplicated(vertices), ]
  edges <- edges[order(edges[, "y.min"]), ]

  # Maintaining an extent is useful.
  bb <- apply(vertices <- vertices[, c("x","y")], 2, function(z) c(min(z), max(z)))

  # Package the output.
  l <- list(v=vertices, e=edges, bb=bb); class(l) <- "polygon"
  l
}
#
# Compute the maximal horizontal interior segments of a polygon.
#
fetch.x <- function(p) {
  #
  # Update moves the line from the previous level to a new, higher level, changing the
  # state to represent all edges originating or strictly passing through level `y`.
  #
  update <- function(y) {
    if (y > state$level) {
      state$level <<- y
      #
      # Remove edges below the new level from state$current.
      #
      current <- state$current
      current <- current[current[, "y.max"] > y, ]
      #
      # Adjoin edges at this level.
      #
      i <- state$i
      while (i <= nrow(p$e) && p$e[i, "y.min"] <= y) {
        current <- rbind(current, p$e[i, ])
        i <- i+1
      }
      state$i <<- i
      #
      # Sort the current edges by x-coordinate.
      #
      x.coord <- function(e, y) {
        if (e["y.max"] > e["y.min"]) {
          ((y - e["y.min"]) * e["x.max"] + (e["y.max"] - y) * e["x.min"]) / (e["y.max"] - e["y.min"])
        } else {
          min(e["x.min"], e["x.max"])
        }
      }
      if (length(current) > 0) {
        x.array <- apply(current, 1, function(e) x.coord(e, y))
        i.x <- order(x.array)
        current <- current[i.x, ]
        x.array <- x.array[i.x]     
        #
        # Scan and mark each interval as interior or exterior.
        #
        status <- FALSE
        interior <- numeric(length(x.array))
        for (i in 1:length(x.array)) {
          if (current[i, "y.max"] == y) {
            interior[i] <- TRUE
          } else {
            status <- !status
            interior[i] <- status
          }
        }
        #
        # Simplify the data structure by retaining the last value of `interior`
        # within each group of common values of `x.array`.
        #
        interior <- sapply(split(interior, x.array), function(i) rev(i)[1])
        x.array <- sapply(split(x.array, x.array), function(i) i[1])

        print(y)
        print(current)
        print(rbind(x.array, interior))


        markers <- c(1, diff(interior))
        intervals <- x.array[markers != 0]
        #
        # Break into a list structure.
        #
        if (length(intervals) > 1) {
          if (length(intervals) %% 2 == 1) 
            intervals <- intervals[-length(intervals)]
          blocks <- 1:length(intervals) - 1
          blocks <- blocks - (blocks %% 2)
          intervals <- split(intervals, blocks)  
        } else {
          intervals <- list()
        }
      } else {
        intervals <- list()
      }
      #
      # Update the state.
      #
      state$current <<- current
    }
    list(y=y, x=intervals)
  } # Update()

  process <- function(intervals, x, y) {
    # intervals is a list of 2-vectors. Each represents the endpoints of
    # an interior interval of a polygon.
    # x is an array of x-coordinates of vertices.
    #
    # Retains only the intervals containing at least one vertex.
    between <- function(i) {
      1 == max(mapply(function(a,b) a && b, i[1] <= x, x <= i[2]))
    }
    is.good <- lapply(intervals$x, between)
    list(y=y, x=intervals$x[unlist(is.good)])
    #intervals
  }
  #
  # Group the vertices by common y-coordinate.
  #
  vertices.x <- split(p$v[, "x"], p$v[, "y"])
  vertices.y <- lapply(split(p$v[, "y"], p$v[, "y"]), max)
  #
  # The "state" is a collection of segments and an index into edges.
  # It will updated during the vertical line sweep.
  #
  state <- list(level=-Inf, current=c(), i=1, x=c(), interior=c())
  #
  # Sweep vertically from bottom to top, processing the intersection
  # as we go.
  #
  mapply(function(x,y) process(update(y), x, y), vertices.x, vertices.y)
}


scale <- 10
p.raw = list(scale * cbind(x=c(0:10,7,6,0), y=c(3,0,0,-1,-1,-1,0,-0.5,0.75,1,4,1.5,0.5,3)),
             scale *cbind(x=c(1,1,2.4,2,4,4,4,4,2,1), y=c(0,1,2,1,1,0,-0.5,1,1,0)),
             scale *cbind(x=c(6,7,6,6), y=c(.5,2,3,.5)))

#p.raw = list(cbind(x=c(0,2,1,1/2,0), y=c(0,0,2,1,0)))
#p.raw = list(cbind(x=c(0, 35, 100, 65, 0), y=c(0, 50, 100, 50, 0)))

p <- as.polygon(p.raw)

results <- fetch.x(p)
#
# Find the longest.
#
dx <- matrix(unlist(results["x", ]), nrow=2)
length.max <- max(dx[2,] - dx[1,])
#
# Draw pictures.
#
segment.plot <- function(s, length.max, colors,  ...) {
  lapply(s$x, function(x) {
      col <- ifelse (diff(x) >= length.max, colors[1], colors[2])
      lines(x, rep(s$y,2), col=col, ...)
    })
}
gray <- "#f0f0f0"
grayer <- "#d0d0d0"
plot(expand(p$bb, 1.1), type="n", xlab="x", ylab="y", main="After the Scan")
sapply(1:length(p.raw), function(i) polygon(p.raw[[i]], col=c(gray, "White", grayer)[i]))
apply(results, 2, function(s) segment.plot(s, length.max, colors=c("Red", "#b8b8a8"), lwd=4))
plot(p, col="Black", lty=3)
points(p, pch=19, col=round(2 + 2*p$v[, "y"]/scale, 0))
points(p, cex=1.25)

क्या कोई प्रमेय है जो यह साबित करता है कि किसी भी दिशा में गैर-उत्तल बहुभुज के भीतर अधिकतम लंबाई रेखा इस बहुभुज के कम से कम एक शीर्ष पर स्थित है?
SS_Rebelious

@ हाँ, वहाँ है। यहां एक प्रमाण का एक स्केच है: यदि कोई चौराहा नहीं है, तो खंड के अंतबिंदु दोनों किनारों के अंदरूनी हिस्से पर झूठ बोलते हैं और खंड को कम से कम, थोड़ा ऊपर और नीचे स्थानांतरित किया जा सकता है। इसकी लंबाई विस्थापन की मात्रा का एक रैखिक कार्य है। इस प्रकार, इसकी अधिकतम लंबाई केवल तभी हो सकती है जब लंबाई को स्थानांतरित करने पर परिवर्तित नहीं होता है। यह दोनों (ए) का तात्पर्य है कि यह अधिकतम लंबाई वाले खंडों से बना एक समांतर चतुर्भुज का हिस्सा है और (ख) उस समांतर चतुर्भुज के शीर्ष और निचले दोनों किनारों को एक शीर्ष, क्यूईडी से मिलना चाहिए।
whuber

और इस प्रमेय का नाम क्या है? मैं इसे खोजने के लिए संघर्ष कर रहा हूं। BTW, घुमावदार किनारों के बारे में क्या जिनका कोई शीर्ष नहीं है (मेरा मतलब सैद्धांतिक दृष्टिकोण है)? मेरे मतलब की आकृति का एक स्केच (एक गूंगा-घंटी के आकार का बहुभुज): "सी = डी"।
SS_Rebelious

@SS जब किनारों को घुमावदार किया जाता है, तो प्रमेय अब धारण नहीं करता है। उपयोगी परिणाम प्राप्त करने के लिए विभेदक ज्यामिति की तकनीकों को लागू किया जा सकता है। मैंने इन तरीकों को Cheeger & Ebin की पुस्तक, तुलनात्मक प्रमेयों की रीमैनियन ज्यामिति से सीखा । हालांकि, अधिकांश जीआईएस वैसे भी विस्तृत पॉलीलाइन द्वारा घटता घटता है, इसलिए प्रश्न (एक व्यावहारिक मामला के रूप में) मूट है।
whuber

क्या आप प्रमेय का नाम निर्दिष्ट कर सकते हैं (और यदि संभव हो तो पृष्ठ)? मुझे पुस्तक मिल गई है और मैं आवश्यक प्रमेय का पता लगाने में सक्षम नहीं था।
SS_Rebelious

9

यहाँ एक रेखापुंज आधारित समाधान है। यह तेज़ है (मैंने 14 मिनट में शुरू से अंत तक सभी काम किए थे), कोई स्क्रिप्टिंग की आवश्यकता नहीं है, केवल कुछ ही ऑपरेशन लगते हैं, और बहुत सटीक है।

बहुभुज के रेखापुंज प्रतिनिधित्व के साथ शुरू करें। यह 550 पंक्तियों और 1200 स्तंभों के ग्रिड का उपयोग करता है:

बहुभुज

इस प्रतिनिधित्व में, ग्रे (अंदर) कोशिकाओं का मूल्य 1 है और अन्य सभी कोशिकाएं NoData हैं।

भार ग्रिड ("वर्षा" की मात्रा) के लिए यूनिट सेल मूल्यों का उपयोग करके पश्चिम-से-पूर्व दिशा में प्रवाह संचय की गणना करें :

प्रवाह संचय

कम संचय अंधेरा है, उज्ज्वल पीले रंग में उच्चतम संचय तक बढ़ रहा है।

एक जोनल अधिकतम (ग्रिड के लिए बहुभुज का उपयोग करना और मूल्यों के लिए प्रवाह संचय) सेल (एस) की पहचान करता है जहां प्रवाह सबसे बड़ा है। इन्हें दिखाने के लिए, मुझे नीचे दाईं ओर ज़ूम इन करना होगा:

ज्यादा से ज्यादा

लाल कोशिकाएं प्रवाह के उच्चतम संचय के सिरों को चिह्नित करती हैं: वे बहुभुज की अधिकतम लंबाई वाले आंतरिक खंडों के सबसे अंतिम छोर हैं।

इन खंडों को खोजने के लिए, लाल कोशिकाओं पर सभी भार रखें और प्रवाह को पीछे की ओर चलाएं!

परिणाम

नीचे की ओर लाल पट्टी कोशिकाओं की दो पंक्तियों को चिह्नित करती है: उनके भीतर अधिकतम लंबाई वाले क्षैतिज खंड होते हैं। आगे के विश्लेषण के लिए इस प्रतिनिधित्व का उपयोग करें या इसे पॉलीलाइन (या बहुभुज) के आकार में परिवर्तित करें।

रेखापुंज प्रतिनिधित्व के साथ कुछ विवेकाधीन त्रुटि है। यह गणना समय में कुछ लागत पर, संकल्प को बढ़ाकर कम किया जा सकता है।


इस दृष्टिकोण का एक बहुत अच्छा पहलू यह है कि आम तौर पर हम एक बड़े वर्कफ़्लो के हिस्से के रूप में चीजों के चरम मूल्यों को पाते हैं जिसमें कुछ उद्देश्य प्राप्त करने की आवश्यकता होती है: एक पाइपलाइन या फुटबॉल क्षेत्र को बैठाना, पारिस्थितिक बफ़र्स बनाना, और इसी तरह। प्रक्रिया में ट्रेड-ऑफ शामिल है। इस प्रकार, सबसे लंबी क्षैतिज रेखा एक इष्टतम समाधान का हिस्सा नहीं हो सकती है। हम यह जानने के बजाय ध्यान रख सकते हैं कि लगभग सबसे लंबी लाइनें कहाँ होंगी। यह सरल है: जोनल अधिकतम प्रवाह का चयन करने के बजाय, जोनल अधिकतम के करीब सभी कोशिकाओं का चयन करें। इस उदाहरण में, जोनल अधिकतम 744 (सबसे लंबे आंतरिक खंड द्वारा फैलाए गए स्तंभों की संख्या) के बराबर है। इसके बजाय, चलो उस अधिकतम के 5% के भीतर सभी कोशिकाओं का चयन करें:

चयनित इष्टतम कोशिकाओं के पास

पूर्व से पश्चिम की ओर बहते हुए क्षैतिज खण्डों का यह संग्रह बनाता है:

लगभग इष्टतम समाधान

यह उन स्थानों का एक नक्शा है जहां निर्बाध पूर्व-पश्चिम सीमा 95% या बहुभुज के भीतर कहीं भी अधिकतम पूर्व-पश्चिम सीमा से अधिक है।


3

ठीक है। मुझे एक और (बेहतर) विचार ( विचार-.2 ) मिला है। लेकिन मुझे लगता है कि यह अजगर स्क्रिप्ट के रूप में महसूस किया जाना बेहतर है, एसक्यूएल-केरी के रूप में नहीं। यहां केवल ईडब्ल्यू ही नहीं, बल्कि आम मामला भी है।

आपको अपने माप की दिशा के रूप में बहुभुज और एज़िमुथ (ए) के लिए एक बाउंडिंग बॉक्स की आवश्यकता होगी। मान लें कि BBox किनारों की लंबाई LA और LB है। एक बहुभुज के भीतर अधिकतम संभव दूरी (एमडी) है: MB = (LA^2 * LB^2)^(1/2)तो मूल्य (वी) की मांग एमबी से बड़ी नहीं है V <= MB:।

  1. BBox के किसी भी शीर्ष से शुरू होकर लंबाई MB और azimuth A के साथ एक रेखा (LL) बनाएँ।
  2. चौराहे लाइन (IL) प्राप्त करने के लिए बहुभुज के साथ अंतः रेखा रेखा LL
  3. आईएल की ज्यामिति की जांच करें - यदि आईएल लाइन में केवल दो बिंदु हैं तो इसकी लंबाई की गणना करें। यदि 4 या अधिक - खंडों की गणना करें और सबसे लंबे समय तक की लंबाई चुनें। नल (कोई चौराहा बिल्कुल नहीं) - अनदेखा करें।
  4. एक अन्य एलएल लाइन बनाएं जो शुरुआती बिंदु काउंटर या क्लॉकवाइज से BBox अनिल के किनारों की ओर बढ़ रही हो।
  5. सबसे बड़ा आईएल लंबाई मान उठाओ (वास्तव में आपको सभी लंबाई स्टोर करने की आवश्यकता नहीं है, आप लूप करते समय केवल 'अब तक' अधिकतम मूल्य रख सकते हैं) - यह वही होगा जो आप चाहते हैं।

यह शीर्ष पर एक डबल लूप की तरह लगता है: यह पर्याप्त अक्षम है कि इसे टाला जाना चाहिए (बहुत सरलीकृत पॉलीथिन को छोड़कर)।
whuber

@ देखें, मुझे यहाँ कोई अतिरिक्त लूप नहीं दिख रहा है। बीबी के 2 पक्षों का सिर्फ कुछ अर्थहीन प्रसंस्करण है जो शून्य के अलावा कुछ भी नहीं देगा। लेकिन इस संसाधन को उस स्क्रिप्ट में बाहर रखा गया था जो मैंने उस उत्तर में प्रदान किया था जिसे यहां हटा दिया गया था (ऐसा लगता है कि यह अब एक टिप्पणी है, लेकिन मैं इसे टिप्पणी के रूप में नहीं देखता - केवल हटाए गए उत्तर के रूप में)
SS_Rebelious

(१) यह तीसरी टिप्पणी है। (२) आप सही कह रहे हैं: अपने विवरण को बहुत ध्यान से पढ़ने पर, यह अब मुझे प्रतीत होता है कि आप बाउंडिंग बॉक्स और बहुभुज के कोने के बीच (चार) के सबसे लंबे खंड को पा रहे हैं। मैं यह नहीं देखता कि यह प्रश्न का उत्तर कैसे देता है, हालांकि: परिणाम निश्चित रूप से वह नहीं है जो ओपी ने मांगा था।
whuber

@whuber, प्रस्तावित एल्गोरिथ्म दिए गए दिशा का प्रतिनिधित्व करने वाली रेखा के साथ बहुभुज का सबसे लंबा चौराहा पाता है। जाहिरा तौर पर परिणाम आईएस क्या पूछा गया था अगर चौराहे की लाइनों के बीच की दूरी -> 0 या यह सभी शीर्षों (घुमावदार आंकड़े नहीं) के लिए गुजरता है।
SS_Rebelious

3

मुझे यकीन नहीं है कि Fetzer का जवाब है कि आप क्या करना चाहते हैं, लेकिन इतना है कि st_box2d काम कर सकता है।

SS_Rebelious का विचार N ° 1 कई मामलों में काम करेगा, लेकिन कुछ अवतल बहुभुजों के लिए नहीं।

मुझे लगता है कि आपको कृत्रिम lw-लाइनों का निर्माण करना चाहिए, जो बिंदुओं को किनारों का पालन करते हैं जब वर्टेक्स-निर्मित लाइनें बहुभुज की सीमाओं को पार करती हैं यदि पूर्व-पश्चिम रेखा की संभावना होती है। एक उदाहरण जहां यह काम नहीं करेगा

इसके लिए आप एक 4 नोड्स बहुभुज बनाने की कोशिश कर सकते हैं जहां लाइन की लंबाई अधिक है, बहुभुज P * बनाएं जो कि आपके साथ मूल बहुभुज से पूर्ववर्ती अतिव्यापी है, और देखें कि क्या मिनट (y1) और अधिकतम (y2) कुछ x-लाइन छोड़ दें संभावना। (जहां y1 शीर्ष बाएं कोने और शीर्ष दाएं कोने के बीच का बिंदु है और y2 आपके 4 नोड्स बहुभुज के निचले बाएं और निचले दाएं कोने के बीच y का सेट है)। यह इतना आसान नहीं है, मुझे आशा है कि आपको आपकी मदद करने के लिए psql टूल मिलेंगे!


यह सही रास्ते पर है। सबसे लंबे ईडब्ल्यू खंड को बहुभुज के आंतरिक भाग के साथ चौराहों के बीच पाया जाएगा जिसमें बहुभुज के कोने से होकर गुजरने वाली क्षैतिज रेखाएं होती हैं। यह कोड को लूप पर लूप के लिए आवश्यक है। बहुभुज के रेखापुंज प्रतिनिधित्व के एक कृत्रिम पूर्व-पश्चिम प्रवाह का पालन करके एक वैकल्पिक (लेकिन समतुल्य) विधि उपलब्ध है : बहुभुज में पाई जाने वाली अधिकतम प्रवाह लंबाई (जो इसके "आंचलिक आँकड़ों में से एक है") वांछित चौड़ाई है। रेखापुंज समाधान केवल 3 या 4 चरणों में प्राप्त किया जाता है और इसमें लूपिंग या स्क्रिप्टिंग की आवश्यकता नहीं होती है।
व्हिबर

@Aname, कृपया गलतफहमी से बचने के लिए "SS_Rebelious के विचार" में ""1" जोड़ें: मैंने अपना प्रस्ताव जोड़ा है। मैं आपके उत्तर को स्वयं संपादित नहीं कर सकता क्योंकि यह संपादन कम है तब 6 वर्ण।
SS_Rebelious

1

मेरे पास एक विचार- (1 है ( संपादित करें: सामान्य मामले के लिए, केवल ईडब्ल्यू दिशा ही नहीं, और कुछ सीमाओं के साथ जो टिप्पणियों में वर्णित हैं)। मैं कोड प्रदान नहीं करूंगा, बस एक अवधारणा। "एक्स-दिशा" वास्तव में एक अज़ीमथ है, जिसकी गणना ST_Azimuth द्वारा की जाती है। प्रस्तावित कदम हैं:

  1. अंक के रूप में बहुभुज से सभी कोने निकालें।
  2. हर जोड़ी बिंदुओं के बीच रेखाएँ बनाएँ।
  3. लाइनों का चयन करें (उन्हें एलडब्ल्यू-लाइनें कहते हैं) जो मूल बहुभुज के भीतर हैं (हमें उन पंक्तियों की आवश्यकता नहीं है जो बहुभुज की सीमाओं को पार करेंगे)।
  4. हर lw- लाइन के लिए दूरी और अज़ीमुथ का पता लगाएं।
  5. Lw-lines से सबसे लंबी दूरी का चयन करें जहाँ azimuth azimuth के लिए समान है या कुछ अंतराल में झूठ है (यह हो सकता है कि azimuth मांगी गई azimuth के बराबर नहीं होगी)।

यह कुछ त्रिकोणों के लिए भी काम करने में विफल होगा , जैसे कि कोने में (0,0), (1000, 1000), और (501, 499)। इसकी अधिकतम पूर्व-पश्चिम चौड़ाई लगभग 2 है; अज़ीमुथ सभी 45 डिग्री के आसपास हैं; और परवाह किए बिना, कोने के बीच की सबसे छोटी लाइन खंड पूर्व-पश्चिम चौड़ाई की तुलना में 350 गुना अधिक है।
व्हिबर

@ आप सही हैं, यह त्रिकोणीय के लिए विफल हो जाएगा, लेकिन बहुभुज के लिए, कुछ प्रकृति सुविधाओं का प्रतिनिधित्व करना उपयोगी हो सकता है।
SS_Rebelious

1
यह एक ऐसी प्रक्रिया की सिफारिश करना मुश्किल है जो इस मामले में सरल मामलों के लिए भी नाटकीय रूप से विफल हो जाती है कि इसे कभी-कभी एक सही उत्तर मिल सकता है!
व्हिबर

@whuber, तो यह सिफारिश नहीं है! ;-) मैंने इस वर्कअराउंड का प्रस्ताव रखा क्योंकि इस सवाल का कोई जवाब नहीं था। ध्यान दें कि आप अपना बेहतर उत्तर पोस्ट कर सकते हैं। BTW, यदि आप त्रिकोण किनारों पर कुछ बिंदु रखेंगे, तो मेरा प्रस्ताव काम करेगा ;-)
SS_Rebelious

मैंने कई दृष्टिकोण सुझाए हैं। एक रास्टर एक gis.stackexchange.com/questions/32552/… पर है और मंचों पर विस्तृत है ।esri.com / Thread.asp ? c= 93 & f=982 & t=107703 & mc3 एक और एक - काफी लागू नहीं है, लेकिन दिलचस्प उपयोग के साथ - gis.stackexchange.com/questions/23664/… (रेडॉन ट्रांसफॉर्म) पर है। यह आँकड़े.स्टैकएक्सचेंज . com / a / 33102 पर चित्रित किया गया है
व्ह्यूबर

1

मेरे सवाल और ईविल जीनियस के जवाब पर एक नज़र है ।

उम्मीद है कि आपकी झील बहुभुज में कई बिंदु हैं, आप इन बिंदुओं पर अज़ीमुथ (पहलू, भू दिशा) के साथ लाइनें बना सकते हैं। लाइनों की लंबाई को पर्याप्त बड़ा (ST_MakePoint भाग) चुनें, ताकि आप दो सबसे दूर रेखाओं के बीच की सबसे छोटी रेखा की गणना कर सकें।

यहाँ एक उदाहरण है:

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

उदाहरण बहुभुज की अधिकतम चौड़ाई दर्शाता है। मैं इस दृष्टिकोण के लिए ST_ShortestLine (लाल रेखा) का चयन करता हूं। ST_MakeLine मान (नीली रेखा) को बढ़ाता है और पंक्ति के अंत बिंदु (नीचे बाईं ओर) बहुभुज की नीली रेखा से टकराता है। आपको निर्मित (सहायता) लाइनों के केंद्रक के साथ दूरी की गणना करना होगा।

इस दृष्टिकोण के लिए अनियमित या अवतल बहुभुज के लिए एक विचार। हो सकता है कि आपको एक रैस्टर के साथ बहुभुज को काटना पड़े।

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