Mapa placu w module Yard Management
W Studio VSS.net wizualizacja zajętości miejsc parkingowych należy do modułu Yard Management. Podkładem mapy jest zdjęcie terenu z góry, na którym narysowano prostokąty stanowisk postojowych. Każde stanowisko ma kod w konwencji 01M, 02M, 03M i kolejne. Dyspozytor i pracownik ochrony posługują się więc tym samym oznaczeniem, które widnieje na tablicy przy placu.
Menu modułu grupuje funkcje placu w jednym miejscu. Mapa odpowiada na pytanie o stan w tej chwili, a lista „Parkowanie” podaje te same dane w tabeli, którą da się filtrować i sortować. Słowniki przewoźników i kontrahentów pochodzą z kartotek systemu VSS.net, więc ikona na mapie prowadzi do pełnych danych transportu.
| Pozycja menu Yard Management | Zastosowanie |
|---|---|
| Kontenery | ewidencja kontenerów przebywających na terenie obiektu |
| Parkowanie | lista zajętych miejsc wraz z pojazdami albo naczepami, które na nich stoją |
| Wizualizacja | mapa placu z kodami stanowisk i ikonami pojazdów |
| Transporty wg statusów | transporty pogrupowane według etapu obsługi |
| Historia | zakończone pobyty i zdarzenia na placu |
| Bramy | obsługa wjazdów i wyjazdów |
| Miejsca parkingowe | konfiguracja stanowisk: kod stanowiska i jego położenie na mapie |
| Transport wewnętrzny | przestawienia pojazdów między strefami zakładu |
Ikony i numeracja stanowisk
Na zajętym stanowisku pojawia się ikona pojazdu. Ciągnik siodłowy ma inny symbol niż odstawiona naczepa, dzięki czemu widać, czy na miejscu stoi kompletny zestaw, czy sama naczepa czekająca na rozładunek. Stanowisko bez ikony jest wolne i można na nie skierować kolejny pojazd.
Numeracja z sufiksem „M” oddziela miejsca postojowe od ramp, które w tym samym systemie mają własne kody. Ma to znaczenie w dyspozycji: pracownik bramy wybiera osobno planowane miejsce parkingowe i osobno planowaną rampę. Pomyłka między tymi dwoma słownikami jest niemożliwa, bo pola korzystają z różnych list.
Źródła danych dla systemu monitorowania zajętości parkingu
Mapa pokazuje tylko to, co zapisano w bazie. Jakość obrazu zależy od tego, które zdarzenie zmienia stan stanowiska i jak szybko trafia ono na serwer. System monitorowania zajętości parkingu łączy zwykle kilka źródeł o różnej wiarygodności i różnym opóźnieniu.
Odprawa na bramie i dyspozycja
Najprostszym źródłem jest odprawa. Pracownik w roli „Brama i ochrona” otwiera zestawienie transportów wjazd/wyjazd, a w oknie „Dyspozycja” wskazuje planowane miejsce parkingowe oraz planowaną rampę magazynową. W tym samym oknie zmienia się status awizacji, na przykład na „Awizacja oczekuje na realizację”. Kierowca zna numer stanowiska, zanim minie szlaban.

Kamery ANPR na wjeździe
Kamera odczytująca tablice rejestracyjne (ANPR, w menu programu pozycja LPR) porównuje numer z listą awizowanych wizyt. Zgodny odczyt zapisuje czas wjazdu bez udziału ochrony. Kamera przy bramie potwierdza jednak tylko wjazd na teren zakładu. Nie wie, na które stanowisko pojazd trafił.

Czujniki na stanowiskach
Czujnik magnetyczny w nawierzchni albo czujnik ultradźwiękowy nad stanowiskiem zgłasza stan zajęty lub wolny niezależnie od wpisów ochrony. Czujnik wykrywa obecność obiektu, lecz go nie identyfikuje. Wie, że stanowisko 05M jest zajęte, ale nie wie przez kogo. Jego odczyt trzeba więc zestawić z dyspozycją albo z odczytem kamery obejmującej plac.
| Źródło zdarzenia | Co potwierdza | Czego nie wie | Opóźnienie zapisu |
|---|---|---|---|
| Dyspozycja na bramie | planowane stanowisko i rampę | czy kierowca faktycznie tam stanął | zależne od operatora |
| Kamera ANPR na wjeździe | tożsamość pojazdu i czas wjazdu | stanowisko na placu | sekundy |
| Czujnik na stanowisku | fizyczne zajęcie miejsca | który pojazd stoi na miejscu | sekundy, zależnie od bramki komunikacyjnej |
| Transport wewnętrzny | przestawienie pojazdu między stanowiskami | stan stanowisk nieobjętych zleceniem | chwila zatwierdzenia zlecenia |
Reguła: stan „zajęte” ustala zdarzenie fizyczne, stan „zarezerwowane” wynika z planu. Nie zapisuje się ich w jednej kolumnie.
Statusy stanowisk i przejścia między nimi
Stan stanowiska zmieniają zdarzenia zapisywane przez bramę oraz przez urządzenia na placu. Przy projektowaniu wizualizacji wygodnie jest opisać go czterema stanami i dozwolonymi przejściami. Taki opis porządkuje kolory mapy oraz reguły walidacji w bazie danych.
| Stan | Zdarzenie wejściowe | Zdarzenie wyjściowe | Znaczenie dla dyspozytora |
|---|---|---|---|
| Wolne | zamknięcie pobytu albo zdjęcie blokady | dyspozycja lub zajęcie bez dyspozycji | można kierować pojazd |
| Zarezerwowane | dyspozycja z planowanym stanowiskiem | wjazd na stanowisko albo wygaśnięcie rezerwacji | stanowisko czeka na konkretny pojazd |
| Zajęte | potwierdzenie z czujnika albo od operatora | wyjazd ze stanowiska | pojazd lub naczepa na miejscu |
| Zablokowane | decyzja administratora | zdjęcie blokady | stanowisko wyłączone z planowania |
Rezerwacja ma sens tylko z terminem ważności. Jeżeli pojazd nie stanie na wskazanym miejscu w określonym czasie, stanowisko wraca do puli wolnych. Bez tej reguły mapa pokazuje plac pełny, choć część stanowisk stoi pusta. Podobny mechanizm opisuje zarządzanie slotami czasowymi, gdzie niewykorzystana rezerwacja blokuje rampę dla innych przewoźników.
Rozbieżność planu i stanu faktycznego
Kierowca, który stanął na 05M zamiast na wskazanym 03M, tworzy dwa błędy naraz. Stanowisko 03M pozostaje zarezerwowane, a czujnik zgłasza zajęcie 05M bez dyspozycji. Taki przypadek system powinien pokazać jako konflikt, a nie cicho nadpisać plan. Ochrona koryguje wtedy dane w module transportu wewnętrznego w VSS.net albo odsyła kierowcę na właściwe miejsce.
Konflikty tego rodzaju warto liczyć. Duża liczba zajęć bez dyspozycji na jednym fragmencie placu zwykle oznacza nieczytelne oznakowanie w terenie, a nie błąd kierowców.
Model miejsc i zdarzeń w SQL Server
Pod mapą leżą dwie tabele: słownik stanowisk i dziennik pobytów. Słownik zmienia się rzadko, najczęściej przy przebudowie placu. Dziennik rośnie z każdym wjazdem, dlatego zajętość liczy się z otwartych pobytów, a nie z kolumny statusu w słowniku. Poniższy schemat ma charakter przykładowy, nazwy tabel nie odpowiadają rzeczywistej bazie produktu.
-- Przykładowy schemat (nazwy poglądowe)
CREATE TABLE dbo.ParkingPlace (
PlaceId int IDENTITY(1,1) PRIMARY KEY,
Code varchar(10) NOT NULL UNIQUE, -- np. 01M
ZoneCode varchar(10) NOT NULL,
IsBlocked bit NOT NULL DEFAULT 0
);
CREATE TABLE dbo.ParkingStay (
StayId bigint IDENTITY(1,1) PRIMARY KEY,
PlaceId int NOT NULL REFERENCES dbo.ParkingPlace(PlaceId),
PlateNumber varchar(15) NOT NULL,
Source tinyint NOT NULL, -- 1 brama, 2 ANPR, 3 czujnik, 4 operator
OccupiedFrom datetime2(0) NOT NULL,
OccupiedTo datetime2(0) NULL,
RowVer rowversion
);
-- jeden otwarty pobyt na stanowisko
CREATE UNIQUE NONCLUSTERED INDEX UX_ParkingStay_Open
ON dbo.ParkingStay (PlaceId)
WHERE OccupiedTo IS NULL;
Unikalny indeks filtrowany z warunkiem WHERE OccupiedTo IS NULL obejmuje wyłącznie otwarte pobyty. Baza sama odrzuci drugie zajęcie tego samego stanowiska, nawet jeśli dwóch operatorów zatwierdzi je w tej samej sekundzie. Indeks pozostaje mały, bo zamknięte pobyty do niego nie trafiają.
CREATE PROCEDURE dbo.usp_OccupyPlace
@PlaceId int,
@PlateNumber varchar(15),
@Source tinyint
AS
BEGIN
SET NOCOUNT ON;
SET XACT_ABORT ON;
BEGIN TRANSACTION;
-- zamknięcie poprzedniego pobytu pojazdu (przestawienie)
UPDATE dbo.ParkingStay
SET OccupiedTo = SYSDATETIME()
WHERE PlateNumber = @PlateNumber
AND OccupiedTo IS NULL;
INSERT INTO dbo.ParkingStay (PlaceId, PlateNumber, Source, OccupiedFrom)
VALUES (@PlaceId, @PlateNumber, @Source, SYSDATETIME());
COMMIT TRANSACTION;
END;
Procedura działa w jednej transakcji z SET XACT_ABORT ON. Naruszenie indeksu unikalnego (błąd 2601) wycofuje całość, więc pojazd nie zostanie zdjęty z poprzedniego stanowiska bez zajęcia nowego. Aplikacja przechwytuje ten błąd i pokazuje operatorowi komunikat o konflikcie.
Zapytanie zasilające mapę
Mapa potrzebuje jednego wiersza na każde stanowisko. Wiersz niesie dane ze słownika i ewentualny otwarty pobyt. Złączenie zewnętrzne ze słownikiem gwarantuje, że wolne stanowiska też trafią do wyniku, tyle że z pustym numerem rejestracyjnym.
SELECT p.Code,
p.ZoneCode,
p.IsBlocked,
s.PlateNumber,
s.OccupiedFrom
FROM dbo.ParkingPlace AS p
LEFT JOIN dbo.ParkingStay AS s
ON s.PlaceId = p.PlaceId
AND s.OccupiedTo IS NULL
ORDER BY p.Code;
Warunek OccupiedTo IS NULL umieszczony w klauzuli ON, a nie w WHERE, zachowuje wolne stanowiska w wyniku. Optymalizator może przy tym użyć indeksu filtrowanego, bo predykat złączenia pokrywa się z jego filtrem. Plan zapytania nie zależy więc od liczby archiwalnych pobytów, które przez lata gromadzą się w dzienniku.
Odczyty bez blokowania zapisów
Mapa czyta dane często, a brama i czujniki zapisują je w tym samym czasie. W domyślnym trybie READ COMMITTED zapytanie mapy zakłada blokady współdzielone i może czekać na transakcję zapisu, która trzyma blokadę wiersza. Opcja READ_COMMITTED_SNAPSHOT przełącza odczyty na wersje wierszy, więc odczyt nie czeka na zapis. Zasady opisuje dokumentacja SET TRANSACTION ISOLATION LEVEL w Microsoft Learn.
ALTER DATABASE YardDemo
SET READ_COMMITTED_SNAPSHOT ON
WITH ROLLBACK IMMEDIATE;
Zmiana wymaga wyłącznego dostępu do bazy, stąd klauzula WITH ROLLBACK IMMEDIATE, która przerywa otwarte sesje. Wykonuje się ją w oknie serwisowym, a nie w trakcie pracy bramy.
Odświeżanie wizualizacji w przeglądarce
Widok w przeglądarce nie musi przeładowywać całej strony. Skrypt co kilkanaście sekund pyta serwer o zmiany i przerysowuje tylko te stanowiska, których stan się zmienił. Poniższy fragment pokazuje ten mechanizm na przykładzie funkcji jQuery.ajax. Adres usługi jest przykładowy.
// Odświeżanie mapy placu (przykład poglądowy)
var lastVersion = 0;
function refreshYard() {
if (document.visibilityState !== 'visible') {
setTimeout(refreshYard, 15000);
return;
}
$.ajax({
url: '/api/yard/changes',
data: { since: lastVersion },
dataType: 'json',
cache: false
}).done(function (res) {
$.each(res.changes, function (i, c) {
$('#place-' + c.code)
.attr('data-state', c.state)
.attr('title', c.plate || '');
});
lastVersion = res.version;
}).always(function () {
setTimeout(refreshYard, 15000);
});
}
refreshYard();
Parametr since przenosi wersję ostatnio otrzymanych danych. Serwer może ją wyznaczyć z kolumny typu rowversion, która zmienia wartość przy każdym INSERT i UPDATE wiersza. Odpowiedź zawiera wtedy tylko zmienione stanowiska, a nie cały plac. Warunek na document.visibilityState wstrzymuje zapytania z kart przeglądarki, których nikt nie ogląda.
| Mechanizm | Opóźnienie widoku | Koszt po stronie serwera | Typowe zastosowanie |
|---|---|---|---|
| Polling AJAX | do jednego interwału | stała liczba zapytań na każde otwarte okno | stanowisko ochrony, ekran dyspozytora |
| Long polling | bliskie zeru | otwarte żądanie HTTP na klienta | kilka równoległych widoków |
| WebSocket (np. SignalR) | bliskie zeru | utrzymanie trwałych połączeń | ekrany ścienne w centrum dyspozytorskim |
Na placu z kilkudziesięcioma stanowiskami polling z interwałem kilkunastu sekund wystarcza. Pojazd nie zmienia miejsca częściej, a ochrona i tak potwierdza wjazd ręcznie. Mechanizm push opłaca się dopiero wtedy, gdy ten sam plac ogląda wiele ekranów naraz.
Wizualizacja zajętości miejsc parkingowych w pracy ochrony
Ochrona korzysta z mapy przy każdym wjeździe. Kierowca bez awizacji trafia do ścieżki „Wjazd nieawizowany”, a pracownik bramy od razu widzi, czy na placu jest miejsce, żeby go wpuścić. Pojazd awizowany dostaje stanowisko z dyspozycji. Proces zgłaszania takich wizyt opisuje artykuł o module awizacji Studio VSS.net.
Dyspozytor patrzy na mapę z innej strony. Zestawia zajęte stanowiska z kolejką do ramp, opisaną w tekście o zarządzaniu dokami w magazynie, i decyduje, którą naczepę podstawić jako następną. Pojazd, który przyjechał przed swoim oknem czasowym, czeka na stanowisku, a nie na drodze dojazdowej.

Wskaźniki z dziennika pobytów
Dziennik pobytów daje więcej niż bieżący obraz placu. Z tych samych wierszy liczy się wskaźniki, które pokazują, gdzie plac traci przepustowość:
- Czas pobytu na stanowisku - różnica między otwarciem a zamknięciem pobytu, liczona osobno dla zestawów i dla samych naczep.
- Obłożenie placu w godzinach - odsetek zajętych stanowisk w każdej godzinie doby, pokazujący szczyty przyjazdów.
- Pobyty bez dyspozycji - zajęcia zgłoszone przez czujnik lub kamerę bez wcześniejszego wskazania z bramy.
- Rezerwacje wygasłe - stanowiska zarezerwowane, na których pojazd nie stanął w terminie.
Długi czas pobytu naczep przy krótkim czasie pobytu zestawów oznacza, że naczepy czekają na wolną rampę, a nie na kierowcę. Takie dane są też materiałem do prognoz opisanych w artykule o cyfrowym bliźniaku magazynu i zatorach przed rampami. Sterowanie samym ruchem między bramą a rampą omawia tekst o sterowaniu ruchem pojazdów na placu.
Zasada: naczepa odstawiona bez ciągnika to osobny pobyt z własnym czasem, a nie część wizyty kierowcy.
Konfiguracja stanowisk przy wdrożeniu
Wdrożenie wizualizacji zaczyna się od słownika w pozycji „Miejsca parkingowe”. Każde stanowisko dostaje kod i obrys na podkładzie mapy. Administrator w module Administrator programu VSS.net przypisuje do bram dostępne rampy i ustala reguły automatycznego przypisywania miejsca postojowego zależnie od typu transportu. W tym samym module bramę łączy się z czytnikiem tablic rejestracyjnych albo z terminalem samoobsługowym.
- Podkład mapy - aktualne zdjęcie terenu z góry albo plan sytuacyjny w skali, na którym obrysy stanowisk pokrywają się z malowaniem na placu.
- Numeracja w terenie - kody na mapie muszą odpowiadać tablicom przy stanowiskach, bo tylko wtedy kierowca trafi na miejsce z dyspozycji.
Wymagania serwerowe są takie same jak dla całego systemu VSS.net: Windows Server z IIS oraz baza SQL Server w edycji Express albo Standard. Edycja Express ogranicza plik danych bazy do 10 GB. Przy dzienniku pobytów, który rośnie z każdym wjazdem, oznacza to potrzebę archiwizacji zamkniętych pobytów, na przykład zadaniem uruchamianym w nocy.
Moduł działa na danych, które powstają przy przyjęciu towaru. Awizacja wskazuje, jaki pojazd przyjedzie, a przyjęcie dostawy do magazynu zamyka jego pobyt na placu. Opis funkcji na stronie producenta zawiera strona wizualizacja zajętości miejsc parkingowych w Studio VSS.net, a platformę YMS w modelu usługowym przedstawia serwis YMS24.





