Heim Backend-Entwicklung Golang So verwenden Sie die Go-Sprache, um die Lieferbereichsfunktion zum Mitnehmen des Bestellsystems zu entwickeln

So verwenden Sie die Go-Sprache, um die Lieferbereichsfunktion zum Mitnehmen des Bestellsystems zu entwickeln

Nov 01, 2023 am 10:33 AM
go语言 Bestellsystem Lieferangebot zum Mitnehmen

So verwenden Sie die Go-Sprache, um die Lieferbereichsfunktion zum Mitnehmen des Bestellsystems zu entwickeln

Mit der Entwicklung des Take-Away-Geschäfts ist die Funktion „Take-Away-Lieferbereich“ zu einem sehr wichtigen Funktionspunkt im Take-Away-Bestellsystem geworden. Um den Bedürfnissen der Nutzer gerecht zu werden, bieten viele Plattformen für die Lieferung von Lebensmitteln eine solche Funktion an. Wie kann man also die Go-Sprache verwenden, um diese Lieferbereichsfunktion zu entwickeln? In diesem Artikel wird dieser Prozess ausführlich vorgestellt und spezifische Codebeispiele bereitgestellt, damit die Leser die Implementierung dieser Funktion besser verstehen und beherrschen können.

  1. Voraussetzungen

Bevor wir mit der Entwicklung beginnen, müssen wir zunächst die Anforderungen und die Implementierung dieser Funktion verstehen. Konkret:

  • Es ist notwendig, einen Polygonbereich anzugeben, d den Standort des Benutzers und entscheidet so, ob Bestellungen angenommen werden sollen.
  • Um diese Funktion zu implementieren, müssen wir einige Tools und Technologien verwenden:

Zuerst müssen wir einen Karten-API-Dienst verwenden, um die benötigten Servicebereichsdaten und die geografischen Informationen zum Standort des Benutzers zu erhalten.
  • Zweitens müssen wir den Polygonalgorithmus verwenden, also den Punkt innerhalb des Polygonalgorithmus, um zu bestimmen, ob der Positionierungspunkt innerhalb des Servicebereichs liegt.
  • Schließlich müssen wir diese Tools zur Verwendung im Bestellsystem in eine Codebibliothek packen.
Designidee
  1. Bevor wir diese Funktion implementieren, müssen wir einige grundlegende Datenstrukturen und Schnittstellen definieren:

Polygonbereich: ein Array, das die geografischen Informationen mehrerer Punkte speichert.
  • Punkt: eine Struktur, die Folgendes enthält: Informationen zum Breiten- und Längengrad;
  • Client-Anfrage: Enthält Benutzeradressinformationen.
  • Dann können wir diese Funktion gemäß den folgenden Entwurfsideen implementieren:

Verwenden Sie einen Karten-API-Dienst, um die geografischen Informationen des Polygonbereichs abzurufen, und speichern Sie diese Informationen in einem Array.
  • Parsen Sie die Client-Anfrage die geografischen Informationen zum Standort des Kunden;
  • Verwenden Sie einen Polygonalgorithmus, um zu bestimmen, ob der Standort des Kunden innerhalb des Servicebereichs liegt, und geben Sie das entsprechende Antwortergebnis aus.
  • In der Go-Sprache können wir die Go-Mapbox-Bibliothek verwenden, um auf den Karten-API-Dienst zuzugreifen. Gleichzeitig können wir auch die integrierte Mathematikbibliothek in der Go-Sprache verwenden, um Polygonalgorithmen zu implementieren. Die spezifische Code-Implementierung lautet wie folgt:
package main

import (
    "fmt"
    "math"
    
    "github.com/ustroetz/go-mapbox"
)

type Point struct {
    Lat float64
    Lng float64
}

type Polygon []Point

func (p Point) ToCoordinates() *mapbox.Coordinates {
    return &mapbox.Coordinates{
        Longitude: p.Lng,
        Latitude:  p.Lat,
    }
}

func ContainsPointInPolygon(point Point, polygon Polygon) bool {
    intersectCount := 0
    polygonLength := len(polygon)

    if polygonLength < 3 {
        return false
    }

    endPoint := Point{Lat: 9999.0, Lng: point.Lng}

    for i := 0; i < len(polygon); i++ {
        startPoint := polygon[i]
        nextPointIndex := (i + 1) % len(polygon)
        nextPoint := polygon[nextPointIndex]

        if startPoint.Lng == nextPoint.Lng && endPoint.Lng == startPoint.Lng && (point.Lng == startPoint.Lng && (point.Lat > startPoint.Lat) == (point.Lat < endPoint.Lat)) {
            return true
        }

        if point.Lng > math.Min(startPoint.Lng, nextPoint.Lng) && point.Lng <= math.Max(startPoint.Lng, nextPoint.Lng) {
            deltaLat := nextPoint.Lat - startPoint.Lat
            if deltaLat == 0 {
                continue
            }
            intersectLat := startPoint.Lat + (point.Lng-startPoint.Lng)*(nextPoint.Lat-startPoint.Lat)/(nextPoint.Lng-startPoint.Lng)
            if intersectLat == point.Lat {
                return true
            }
            if intersectLat > point.Lat {
                intersectCount++
            }
        }
    }

    return intersectCount%2 != 0
}

func InDeliveryArea(point Point, apiKey string) bool {
    client := mapbox.New(apiKey)

    // 可以使用自己的多边形坐标
    geojson, _, _ := client.MapMatching().GetMapMatching(
        []mapbox.Coordinates{
            *point.ToCoordinates(),
        },
           nil,
    )
    polygon := geojson.Features[0].Geometry.Coordinates[0].([]interface{})
    var polygonArray Polygon
    for _, item := range polygon {
        arr := item.([]interface{})
        p := Point{Lat: arr[1].(float64), Lng: arr[0].(float64)}
        polygonArray = append(polygonArray, p)
    }
    fmt.Println("多边形坐标: ", polygonArray)

    return ContainsPointInPolygon(point, polygonArray)
}

func main() {
    point := Point{
        Lat: 31.146922,
        Lng: 121.362282,
    }

    apiKey := "YOUR_ACCESS_TOKEN"

    result := InDeliveryArea(point, apiKey)

    fmt.Println("坐标是否在配送范围内:", result)
}
Nach dem Login kopieren

Das Obige ist ein grundlegendes Codebeispiel für die Go-Sprachimplementierung. Bevor Sie diesen Code ausführen, müssen Sie zunächst ein Zugriffstoken aus dem Karten-API-Hintergrund abrufen. Ersetzen Sie einfach YOUR_ACCESS_TOKEN durch Token. Darüber hinaus müssen Sie die entsprechenden Koordinaten und zugehörigen Parameter in die von der Karten-API bereitgestellte Polygon-Abfrageschnittstelle eingeben. Wenn Sie den obigen Code ausführen, können Sie einen booleschen Wert erhalten, der angibt, ob die Koordinatenposition innerhalb des Servicebereichs liegt.

    Eingekapselt in eine wiederverwendbare BibliothekYOUR_ACCESS_TOKEN即可。另外,还需要在地图API提供的多边形查询接口中输入对应的坐标和相关参数。运行以上代码,可以得到一个代表坐标所在位置是否在服务范围内的布尔值。

    1. 封装成为可复用库

    上述示例代码可以帮助我们完成外卖点餐系统的外卖配送范围功能。但是,在实际应用中,这个功能可能被多个页面或模块所使用。为了避免重复编写代码的麻烦,我们需要将其封装成为一个可复用的库。具体而言:

    • 我们可以将上述的InDeliveryArea函数封装成为一个可以从外部调用的函数。
    • 另外,我们还可以对外部输入的参数进行检查和校验,以保证程序的健壮性。

    例如,我们可以将代码重新组织,把获取多边形和判断点在多边形内两个操作分离,这样也方便后续扩展。

    以下是Go语言封装成为可复用库的示例代码:

    package delivery
    
    import (
        "fmt"
        "math"
        
        "github.com/ustroetz/go-mapbox"
    )
    
    type Point struct {
        Lat float64
        Lng float64
    }
    
    type Polygon []Point
    
    type DeliveryArea struct {
        polygon Polygon
        client  *mapbox.Client
    }
    
    func NewDeliveryArea(apiKey string, polygonArray []Point) *DeliveryArea {
        client := mapbox.New(apiKey)
    
        var polygon Polygon
        for _, p := range polygonArray {
            polygon = append(polygon, p)
        }
    
        return &DeliveryArea{polygon: polygon, client: client}
    }
    
    func (p Point) ToCoordinates() *mapbox.Coordinates {
        return &mapbox.Coordinates{
            Longitude: p.Lng,
            Latitude:  p.Lat,
        }
    }
    
    func (d *DeliveryArea) containsPoint(point Point) bool {
        intersectCount := 0
        polygonLength := len(d.polygon)
    
        if polygonLength < 3 {
            return false
        }
    
        endPoint := Point{Lat: 9999.0, Lng: point.Lng}
    
        for i := 0; i < len(d.polygon); i++ {
            startPoint := d.polygon[i]
            nextPointIndex := (i + 1) % len(d.polygon)
            nextPoint := d.polygon[nextPointIndex]
    
            if startPoint.Lng == nextPoint.Lng && endPoint.Lng == startPoint.Lng && (point.Lng == startPoint.Lng && (point.Lat > startPoint.Lat) == (point.Lat < endPoint.Lat)) {
                return true
            }
    
            if point.Lng > math.Min(startPoint.Lng, nextPoint.Lng) && point.Lng <= math.Max(startPoint.Lng, nextPoint.Lng) {
                deltaLat := nextPoint.Lat - startPoint.Lat
                if deltaLat == 0 {
                    continue
                }
                intersectLat := startPoint.Lat + (point.Lng-startPoint.Lng)*(nextPoint.Lat-startPoint.Lat)/(nextPoint.Lng-startPoint.Lng)
                if intersectLat == point.Lat {
                    return true
                }
                if intersectLat > point.Lat {
                    intersectCount++
                }
            }
        }
    
        return intersectCount%2 != 0
    }
    
    func (d *DeliveryArea) Contains(point Point) bool {
        resp, _, err := d.client.MapMatching().GetMapMatching(
            []mapbox.Coordinates{
                *point.ToCoordinates(),
            },
               nil,
        )
        if err != nil {
            fmt.Printf("MapMatching error: %s
    ", err)
            return false
        }
        geojson := resp.Features[0].Geometry.Coordinates[0].([]interface{})
    
        var polygonArray Polygon
        for _, item := range geojson {
            arr := item.([]interface{})
            p := Point{Lat: arr[1].(float64), Lng: arr[0].(float64)}
            polygonArray = append(polygonArray, p)
        }
    
        return d.containsPoint(point)
    }
    Nach dem Login kopieren

    这里我们使用了工厂模式来创建DeliveryArea结构体,可以看到,除了方便使用外,还可以发现它们的内部逻辑相对清晰,继而更易于维护。如下是一个使用上述封装后库的示例代码:

    package main
    
    import (
        "fmt"
    
        "github.com/username/repo_deliver_area/delivery"
    )
    
    func main() {
        polygonArray := []delivery.Point{
            {Lat: 31.23039, Lng: 121.4737},
            {Lat: 31.23886, Lng: 121.50016},
            {Lat: 31.19394, Lng: 121.5276},
            {Lat: 31.18667, Lng: 121.49978},
        }
    
        apiKey := "YOUR_ACCESS_TOKEN"
    
        deliveryArea := delivery.NewDeliveryArea(apiKey, polygonArray)
    
        point := delivery.Point{
            Lat: 31.146922,
            Lng: 121.362282,
        }
    
        result := deliveryArea.Contains(point)
    
        fmt.Println(result)
    }
    Nach dem Login kopieren

    在运行这段代码之前,需要先将库文件放置到指定位置,并替换掉Import路径中的username/repo_deliver_area,以及将地图API的Access Token替换掉 YOUR_ACCESS_TOKEN

    🎜Der obige Beispielcode kann uns dabei helfen, die Lieferbereichsfunktion zum Mitnehmen des Bestellsystems zum Mitnehmen zu vervollständigen. In tatsächlichen Anwendungen kann diese Funktion jedoch von mehreren Seiten oder Modulen verwendet werden. Um die Mühe des wiederholten Schreibens von Code zu vermeiden, müssen wir ihn in einer wiederverwendbaren Bibliothek kapseln. Konkret: 🎜🎜🎜Wir können die obige InDeliveryArea-Funktion in eine Funktion kapseln, die von außen aufgerufen werden kann. 🎜🎜Darüber hinaus können wir auch externe Eingabeparameter überprüfen und verifizieren, um die Robustheit des Programms sicherzustellen. 🎜🎜🎜Zum Beispiel können wir den Code neu organisieren und die beiden Vorgänge zum Erhalten von Polygonen und Beurteilen von Punkten innerhalb von Polygonen trennen, was auch die spätere Erweiterung erleichtert. 🎜🎜Das Folgende ist ein Beispielcode, der die Go-Sprache in eine wiederverwendbare Bibliothek kapselt: 🎜rrreee🎜Hier verwenden wir das Factory-Muster, um die DeliveryArea-Struktur zu erstellen. Wie Sie sehen, ist es nicht nur bequem zu verwenden, sondern auch dass ihre interne Logik relativ klar ist, was wiederum die Wartung erleichtert. Das Folgende ist ein Beispielcode, der die oben gekapselte Bibliothek verwendet: 🎜rrreee🎜 Bevor Sie diesen Code ausführen, müssen Sie die Bibliotheksdatei am angegebenen Speicherort platzieren und username/repo_deliver_area im Importpfad ersetzen das Zugriffstoken der Karten-API mit YOUR_ACCESS_TOKEN. Die endgültige Ausgabe ist ein boolescher Wert, der angibt, ob die Position der Koordinate innerhalb des Servicebereichs liegt. 🎜

    Das obige ist der detaillierte Inhalt vonSo verwenden Sie die Go-Sprache, um die Lieferbereichsfunktion zum Mitnehmen des Bestellsystems zu entwickeln. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

Video Face Swap

Video Face Swap

Tauschen Sie Gesichter in jedem Video mühelos mit unserem völlig kostenlosen KI-Gesichtstausch-Tool aus!

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Welche Bibliotheken werden für die Operationen der schwimmenden Punktzahl in Go verwendet? Welche Bibliotheken werden für die Operationen der schwimmenden Punktzahl in Go verwendet? Apr 02, 2025 pm 02:06 PM

In der Bibliothek, die für den Betrieb der Schwimmpunktnummer in der GO-Sprache verwendet wird, wird die Genauigkeit sichergestellt, wie die Genauigkeit ...

Was ist das Problem mit Warteschlangen -Thread in Go's Crawler Colly? Was ist das Problem mit Warteschlangen -Thread in Go's Crawler Colly? Apr 02, 2025 pm 02:09 PM

Das Problem der Warteschlange Threading In Go Crawler Colly untersucht das Problem der Verwendung der Colly Crawler Library in Go -Sprache. Entwickler stoßen häufig auf Probleme mit Threads und Anfordern von Warteschlangen. � ...

Warum hat das Drucken von Saiten mit Println und String () -Funktionen unterschiedliche Effekte? Warum hat das Drucken von Saiten mit Println und String () -Funktionen unterschiedliche Effekte? Apr 02, 2025 pm 02:03 PM

Der Unterschied zwischen Stringdruck in GO -Sprache: Der Unterschied in der Wirkung der Verwendung von Println und String () ist in Go ...

Wie löste ich das Problem des Typs des user_id -Typs bei der Verwendung von Redis -Stream, um Nachrichtenwarteschlangen in GO -Sprache zu implementieren? Wie löste ich das Problem des Typs des user_id -Typs bei der Verwendung von Redis -Stream, um Nachrichtenwarteschlangen in GO -Sprache zu implementieren? Apr 02, 2025 pm 04:54 PM

Das Problem der Verwendung von RETISTREAM zur Implementierung von Nachrichtenwarteschlangen in der GO -Sprache besteht darin, die Go -Sprache und Redis zu verwenden ...

Was soll ich tun, wenn die benutzerdefinierten Strukturbezeichnungen in Goland nicht angezeigt werden? Was soll ich tun, wenn die benutzerdefinierten Strukturbezeichnungen in Goland nicht angezeigt werden? Apr 02, 2025 pm 05:09 PM

Was soll ich tun, wenn die benutzerdefinierten Strukturbezeichnungen in Goland nicht angezeigt werden? Bei der Verwendung von Goland für GO -Sprachentwicklung begegnen viele Entwickler benutzerdefinierte Struktur -Tags ...

Was ist der Unterschied zwischen 'var' und 'Typ' Typenwort Definition in der GO -Sprache? Was ist der Unterschied zwischen 'var' und 'Typ' Typenwort Definition in der GO -Sprache? Apr 02, 2025 pm 12:57 PM

Zwei Möglichkeiten, Strukturen in der GO -Sprache zu definieren: Der Unterschied zwischen VAR- und Typ -Schlüsselwörtern. Bei der Definition von Strukturen sieht die Sprache oft zwei verschiedene Schreibweisen: Erstens ...

Welche Bibliotheken in GO werden von großen Unternehmen entwickelt oder von bekannten Open-Source-Projekten bereitgestellt? Welche Bibliotheken in GO werden von großen Unternehmen entwickelt oder von bekannten Open-Source-Projekten bereitgestellt? Apr 02, 2025 pm 04:12 PM

Welche Bibliotheken in GO werden von großen Unternehmen oder bekannten Open-Source-Projekten entwickelt? Bei der Programmierung in Go begegnen Entwickler häufig auf einige häufige Bedürfnisse, ...

Warum gibt es bei Verwendung von SQL.Open keinen Fehler an, wenn DSN leer ist? Warum gibt es bei Verwendung von SQL.Open keinen Fehler an, wenn DSN leer ist? Apr 02, 2025 pm 12:54 PM

Warum meldet der DSN bei Verwendung von SQL.Open keinen Fehler? In Go Language, Sql.open ...

See all articles