Changes between Version 4 and Version 5 of AdvancedConcepts


Ignore:
Timestamp:
06/15/26 19:30:14 (33 hours ago)
Author:
231028
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • AdvancedConcepts

    v4 v5  
    33Во оваа фаза од проектот, стандардниот релационен модел е надограден со просторни функционалности преку екстензијата PostGIS. Дополнително, за следење на возилата е имплементирана Lambda архитектура (Hot/Cold складирање) со 4D просторно-временски траектории (LineStringZM).
    44
    5 1. Иницијализација на PostGIS и конверзија во полигони (Geofencing)
     5** Иницијализација на PostGIS и конверзија во полигони (Geofencing) **
     6
    67Првиот чекор вклучува овозможување на PostGIS екстензијата и мигрирање на постоечките координати во geometry објекти. Дополнителна промена е отфрлањето на обичните радиуси за зоните на компаниите. Наместо тоа, користејќи ја функцијата ST_Buffer, кружните области се конвертирани во прецизни полигони со што се овозможува вистинско дигитално надградување. Креирани се и GiST (Generalized Search Tree) индекси кои се потребни за брзо пребарување на просторни податоци.
    78
     
    5051}}}
    5152
    52 2. Просторно филтрирање на барања (Spatial Join)
     53** Просторно филтрирање на барања (Spatial Join) **
    5354За ефикасно поврзување на патниците со релевантните такси компании, креиран е нов поглед кој користи просторно спојување (Spatial Join). Преку функцијата ST_Contains, погледот проверува дали почетната локација на патникот (start_location) се наоѓа во рамките на полигонот на покриеност на компанијата (coverage_polygon). Овој пристап е многу поефикасен од пресметување на растојанија. Ова е оптимизацијата која ги подобрува перформансите на погледот vw_unassigned_requests спомнат во делот за QueryOptimization каде почетно беше решено со пагинација на барањата, а во случајот се земаат помал број на барања поради тоа што ќе се земат само барања кои се наоѓаат во одреден радиус.
    5455
     
    7475where r.status = 'pending';
    7576}}}
     77
     78**Динамична пресметка на цена преку просторна дистанца**
     79
     80Креирана е нова функција calculate_price која ја пресметува цената на возењето. Таа користи ST_Distance со кастирање во geography за да ја добие точната воздушна дистанца во километри помеѓу почетната и крајната дестинација, по што го множи растојанието со соодветната тарифа на компанијата или фриленсерот. Тарифата може да биде цена за секоја минута возење или цена за секој изминат километар.
     81
     82{{{
     83CREATE OR REPLACE FUNCTION calculate_price(request_id int4, id_company int4, id_area int4, freelance_driver_id int4)
     84RETURNS numeric(19,2)
     85LANGUAGE plpgsql
     86AS
     87$$
     88DECLARE
     89    distance_km numeric;
     90    price_per_km numeric;
     91    price_per_min numeric;
     92BEGIN
     93    SELECT
     94        ST_Distance(
     95            start_location::geography,
     96            end_location::geography
     97        ) / 1000.0
     98    INTO distance_km
     99    FROM request
     100    WHERE id = request_id;
     101
     102    IF distance_km IS NULL THEN
     103        RAISE EXCEPTION 'Request % not found', request_id;
     104    END IF;
     105
     106    SELECT value
     107    INTO price_per_km
     108    FROM pricinginfo p
     109    JOIN company_area c on p.id=c.pricing_info_id
     110    WHERE c.company_id=id_company and c.area_id=id_area and unit='kilometer'
     111    LIMIT 1;
     112
     113    SELECT value
     114    INTO price_per_km
     115    FROM pricinginfo p
     116    JOIN freelancedriver d on p.id=d.pricing_info_id
     117    WHERE d.driver_user_id=freelance_driver_id and unit='kilometer'
     118    LIMIT 1;
     119
     120    SELECT value
     121    INTO price_per_min
     122    FROM pricinginfo p
     123    JOIN company_area c on p.id=c.pricing_info_id
     124    WHERE c.company_id=id_company and c.area_id=id_area and unit='minute'
     125    LIMIT 1;
     126
     127    SELECT value
     128    INTO price_per_min
     129    FROM pricinginfo p
     130    JOIN freelancedriver d on p.id=d.pricing_info_id
     131    WHERE d.driver_user_id=freelance_driver_id and unit='minute'
     132    LIMIT 1;
     133
     134    IF price_per_km IS NULL and price_per_min IS NULL
     135    THEN
     136        RAISE EXCEPTION 'Pricing info not found';
     137    end if;
     138
     139    IF price_per_km IS NOT NULL
     140    THEN
     141        RETURN ROUND((distance_km * price_per_km)::numeric, 2);
     142    ELSE
     143        RETURN ROUND((distance_km/40 * price_per_min * 60)::numeric, 2);
     144    end if;
     145END;
     146$$;
     147}}}