|
From: <aka...@us...> - 2013-10-02 13:57:03
|
Revision: 323
http://sourceforge.net/p/advance-project/code/323
Author: akarnokd
Date: 2013-10-02 13:57:00 +0000 (Wed, 02 Oct 2013)
Log Message:
-----------
Demo refactor and more things implemented
Modified Paths:
--------------
advance-live-reporter-os/src/eu/advance/logistics/live/reporter/model/LorryPosition.java
Added Paths:
-----------
advance-live-reporter-os/src/eu/advance/logistics/live/reporter/demo/
advance-live-reporter-os/src/eu/advance/logistics/live/reporter/demo/CompareFirst.java
advance-live-reporter-os/src/eu/advance/logistics/live/reporter/demo/Cons.java
advance-live-reporter-os/src/eu/advance/logistics/live/reporter/demo/ConsItem.java
advance-live-reporter-os/src/eu/advance/logistics/live/reporter/demo/ConsignmentCreator.java
advance-live-reporter-os/src/eu/advance/logistics/live/reporter/demo/Demo.java
advance-live-reporter-os/src/eu/advance/logistics/live/reporter/demo/DepotAgent.java
advance-live-reporter-os/src/eu/advance/logistics/live/reporter/demo/EnvironmentAgent.java
advance-live-reporter-os/src/eu/advance/logistics/live/reporter/demo/HubAgent.java
advance-live-reporter-os/src/eu/advance/logistics/live/reporter/demo/VehicleAgent.java
advance-live-reporter-os/src/eu/advance/logistics/live/reporter/demo/WarehouseAgent.java
advance-live-reporter-os/src/eu/advance/logistics/live/reporter/demo/package-info.java
Removed Paths:
-------------
advance-live-reporter-os/src/eu/advance/logistics/live/reporter/db/Demo.java
Deleted: advance-live-reporter-os/src/eu/advance/logistics/live/reporter/db/Demo.java
===================================================================
--- advance-live-reporter-os/src/eu/advance/logistics/live/reporter/db/Demo.java 2013-10-01 16:15:09 UTC (rev 322)
+++ advance-live-reporter-os/src/eu/advance/logistics/live/reporter/db/Demo.java 2013-10-02 13:57:00 UTC (rev 323)
@@ -1,624 +0,0 @@
-/*
- * Copyright 2010-2013 The Advance EU 7th Framework project consortium
- *
- * This file is part of Advance.
- *
- * Advance is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * Advance is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Advance. If not, see
- * <http://www.gnu.org/licenses/>.
- *
- */
-package eu.advance.logistics.live.reporter.db;
-
-import gnu.trove.map.TLongObjectMap;
-import gnu.trove.map.hash.TLongObjectHashMap;
-import hu.akarnokd.utils.crypto.BCrypt;
-import hu.akarnokd.utils.database.DB;
-import hu.akarnokd.utils.sequence.SequenceUtils;
-
-import java.awt.Point;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-import java.util.Set;
-
-import org.joda.time.DateMidnight;
-import org.joda.time.DateTime;
-import org.joda.time.DateTimeConstants;
-import org.joda.time.LocalTime;
-
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.Multimap;
-
-import eu.advance.logistics.live.reporter.model.Consignment;
-import eu.advance.logistics.live.reporter.model.Depot;
-import eu.advance.logistics.live.reporter.model.Hub;
-import eu.advance.logistics.live.reporter.model.Item;
-import eu.advance.logistics.live.reporter.model.ItemEventType;
-import eu.advance.logistics.live.reporter.model.Postcode;
-import eu.advance.logistics.live.reporter.model.ServiceLevel;
-import eu.advance.logistics.live.reporter.model.StorageArea;
-import eu.advance.logistics.live.reporter.model.UserView;
-import eu.advance.logistics.live.reporter.model.Vehicle;
-import eu.advance.logistics.live.reporter.model.Warehouse;
-
-/**
- * Prepares the database with demo data.
- * @author karnokd, 2013.09.24.
- */
-public final class Demo {
- /** Demo. */
- private Demo() { }
- /**
- * The demo program.
- * @param args no arguments
- * @throws Exception ignored
- */
- public static void main(String[] args) throws Exception {
- try (DB db = DB.connect()) {
- createMaster(db);
-
- db.commit();
-
- ConsignmentCreator cc = new ConsignmentCreator(db);
- cc.init();
- cc.run();
- cc.done();
-
- db.commit();
- }
- }
- /**
- * Create the basic hubs and depots.
- * @param db the database connection
- * @throws SQLException on error
- */
- private static void createMaster(DB db) throws SQLException {
- // create hubs
- int nHubs = 2;
- for (int i = 1; i <= nHubs; i++) {
- db.update("INSERT IGNORE INTO hubs VALUES (?, ?, ?, ?)", i, "Hub " + i, 1000, 1000);
- }
-
- // create depots
- int nDepots = 20;
- for (int i = 1; i <= nDepots; i++) {
- db.update("INSERT IGNORE INTO depots VALUES (?, ?) ", i, "Depot " + i);
-
- int nVehicles = (int)Math.ceil(5d * i / nDepots);
-
- for (int j = 1; j <= nVehicles; j++) {
- db.update("INSERT IGNORE INTO vehicles VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
- "D" + i + "V" + j, i, Integer.class, Integer.class, 50, 4, 4, 15, 4000
- );
- }
- }
-
- // create warehouses per hub
- int nWarehouses = 4;
- int nLorryPositions = 4;
-
- Random rnd = new Random(0);
-
- for (int i = 1; i <= nHubs; i++) {
- for (int j = 1; j <= nWarehouses; j++) {
- int x = 500 + (j % 2 == 1 ? -100 : 100);
- int y = 500 + (j % 2 == 1 ? -150 : 150);
- int wi = ((i - 1) * nWarehouses + j);
- db.update("INSERT IGNORE INTO warehouses VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
- i, "Warehouse " + wi, x, y, 60, 100, 0, rnd.nextInt(5) + 5, "Warehouse " + (wi % 2 == 0 ? wi - 1 : wi + 1));
-
- int sa = (nDepots / 2) * ((j - 1) / 2);
- for (int k = 0; k < nDepots / 2; k++) {
- db.update("INSERT IGNORE INTO storage_areas VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
- i, "Warehouse " + wi, k % 2, k / 2, sa + k + 1, 20, 1.5, 0, 30
- );
- }
- for (int k = 0; k < nLorryPositions; k++) {
- int lx = k % 2 == 0 ? 23 : 32;
- int ly = k / 2 == 0 ? 10 : 60;
-
- int et = k / 2 == 0 ? 15 : 30;
- int lt = k / 2 == 0 ? 30 : 15;
-
- db.update("INSERT IGNORE INTO lorry_positions VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) ",
- i, "Warehouse " + wi, k, lx, ly, 5, 20, et, lt);
- }
- }
- }
-
-
- // create hub, warehouse and depot users
- for (int i = 1; i <= nHubs; i++) {
- db.update("INSERT IGNORE INTO users (name, hub, depot, admin, default_view, password) VALUES (?, ?, ?, ?, ?, ?)",
- "admin" + i, 1, Long.class, true, UserView.HUB.ordinal(), BCrypt.hashpw("admin" + i, BCrypt.gensalt()));
-
- db.update("INSERT IGNORE INTO users (name, hub, depot, admin, default_view, password) VALUES (?, ?, ?, ?, ?, ?)",
- "hub" + i, 1, Long.class, false, UserView.HUB.ordinal(), BCrypt.hashpw("hub" + i, BCrypt.gensalt()));
-
- db.update("INSERT IGNORE INTO users (name, hub, depot, admin, default_view, password) VALUES (?, ?, ?, ?, ?, ?)",
- "warehouse" + i, 1, Long.class, true, UserView.WAREHOUSE.ordinal(), BCrypt.hashpw("warehouse" + i, BCrypt.gensalt()));
- }
-
- for (int i = 1; i <= nDepots; i++) {
- db.update("INSERT IGNORE INTO users (name, hub, depot, admin, default_view, password) VALUES (?, ?, ?, ?, ?, ?)",
- "depot" + i, 1, i, false, UserView.HUB.ordinal(), BCrypt.hashpw("depot" + i, BCrypt.gensalt()));
- }
-
-
- // create holidays
- int nStartYear = 2013;
- int nEndYear = 2020;
- for (int y = nStartYear; y <= nEndYear; y++) {
- db.update("INSERT IGNORE INTO holidays VALUES (?)", new DateMidnight(y, 1, 1));
- db.update("INSERT IGNORE INTO holidays VALUES (?)", new DateMidnight(y, 12, 25));
- db.update("INSERT IGNORE INTO holidays VALUES (?)", new DateMidnight(y, 12, 26));
- db.update("INSERT IGNORE INTO holidays VALUES (?)", new DateMidnight(y, 12, 31));
- }
-
- int nPostcodes = 2000;
- for (int i = 0; i < nPostcodes; i++) {
- String pcg = "X" + (char)('A' + (i / 100));
-
- String pc = String.format("%s%02d", pcg, i % 100);
-
- db.update("INSERT IGNORE INTO postcodes VALUES (?, ?, ?) ",
- i + 1, pc, pcg);
- }
- }
- /**
- * Returns the position of a postcode.
- * @param postcode the postcode in form 'XA00'
- * @return the position
- */
- static Point postcodeLocation(String postcode) {
- int c = postcode.charAt(1) - 'A';
- int n = Integer.parseInt(postcode.substring(2));
-
- return new Point(n, c * 3);
- }
- /**
- * Returns the depot position.
- * @param depot the depot
- * @return the
- */
- static Point depotLocation(long depot) {
- int x = (int)(16 + 16 * ((depot - 1) % 5));
- int y = (int)(10 + 10 * ((depot - 1) / 5));
-
- return new Point(x, y);
- }
- /**
- * Returns the position of the hub.
- * @param hub the hub id
- * @return the position
- */
- static Point hubLocation(long hub) {
- return new Point((int)(hub * 33), 30);
- }
- /**
- * The consignment item with back-reference to the consignment itself.
- * @author karnokd, 2013.10.01.
- */
- static class ConsItem extends Item {
- /** The parent consignment. */
- public Cons consignment;
- }
- /** The created consignment. */
- static class Cons extends Consignment {
- /** The consignment items. */
- public final List<ConsItem> items = new ArrayList<>();
- }
- /**
- * The base agent class.
- * @author karnokd, 2013.10.01.
- */
- static class BaseAgent {
- /** The database connection. */
- DB db;
- /**
- * Set the database connection.
- * @param db the database connection
- */
- public void setDb(DB db) {
- this.db = db;
- }
- }
- /**
- * A depot manager "agent".
- * @author karnokd, 2013.10.01.
- *
- */
- static class DepotAgent extends BaseAgent {
- /** Depot identifier. */
- public long id;
- /** The items to deliver. */
- public final List<ConsItem> toDelivery = new ArrayList<>();
- /** The items to dispatch. */
- public final List<ConsItem> toDispatch = new ArrayList<>();
- /** The list of vehicles. */
- public final List<VehicleAgent> vehicles = new ArrayList<>();
-
- }
- /**
- * A vehicle delivering items to and from hub.
- * @author karnokd, 2013.10.01.
- */
- static class VehicleAgent extends BaseAgent {
- /** The id. */
- public String id;
- /** The owner/target depot. */
- public long depot;
- /** The vehicle capacity. */
- public int capacity;
- /** The target hub, if moving towards it. */
- public Long targetHub;
- /** The session identifier. */
- public String sessionId;
- /** In a warehouse if not null. */
- public String warehouse;
- /** In a lorry position if not null. */
- public Integer position;
- /** The contents. */
- public final List<ConsItem> contents = new ArrayList<>();
- }
- /**
- * The hub agent.
- * @author karnokd, 2013.10.01.
- */
- static class HubAgent extends BaseAgent {
- /** Identifier. */
- public long id;
- /** List of vehicles on site. */
- public final List<VehicleAgent> vehiclesOnSite = new ArrayList<>();
- /** List of vehicles. */
- public final List<WarehouseAgent> warehouses = new ArrayList<>();
- }
- /**
- * A warehouse managing items.
- * @author karnokd, 2013.10.01.
- */
- static class WarehouseAgent extends BaseAgent {
- /** The hub. */
- public long hub;
- /** The warehouse. */
- public String warehouse;
- /** The depots and the current contents. */
- public final Multimap<Long, ConsItem> storageAreas = HashMultimap.create();
- /** List of vehicles on site. */
- public final List<VehicleAgent> vehicles = new ArrayList<>();
- }
- /**
- * Consignment creator.
- * @author karnokd, 2013.10.01.
- *
- */
- static class ConsignmentCreator {
- /** The database connection. */
- DB db;
- /** Field. */
- private List<Postcode> postcodes;
- /** Field. */
- private TLongObjectMap<Postcode> postcodeMap;
- /** Field. */
- private List<Vehicle> vehicles;
- /** Field. */
- private Multimap<Long, Vehicle> depotVehicles;
- /** Field. */
- private List<Hub> hubs;
- /** Field. */
- private TLongObjectMap<Hub> hubMap;
- /** Field. */
- private List<Depot> depots;
- /** Field. */
- private TLongObjectMap<Depot> depotMap;
- /** Field. */
- private Set<DateMidnight> holidays;
- /** Field. */
- private List<Warehouse> warehouses;
- /** Field. */
- private Multimap<Long, Warehouse> warehouseMap;
- /** Field. */
- private List<StorageArea> storages;
- /** Field. */
- private Multimap<String, StorageArea> areas;
- /** Field. */
- private TLongObjectMap<Depot> postcodeClosestDepot;
- /** Field. */
- private TLongObjectMap<Hub> depotClosestHub;
- /** The running consignment id. */
- private long consId;
- /** The running item ids. */
- private long itemId;
- /** The map of depots. */
- private final TLongObjectMap<DepotAgent> depotAgents = new TLongObjectHashMap<>();
- /** The map of vehicles. */
- private final TLongObjectMap<VehicleAgent> vehicleAgents = new TLongObjectHashMap<>();
- /** The map of warehouses. */
- private final Map<String, WarehouseAgent> warehouseAgents = new HashMap<>();
- /** The map of hub agents. */
- private final TLongObjectMap<HubAgent> hubAgents = new TLongObjectHashMap<>();
- /**
- * Constructor, sets the database connection.
- * @param db the database connection
- */
- public ConsignmentCreator(DB db) {
- this.db = db;
- }
- /**
- * Initializes the environment.
- * @throws SQLException ignored
- */
- public void init() throws SQLException {
- postcodes = db.queryReadOnly("SELECT * FROM postcodes", Postcode.SELECT);
- postcodeMap = new TLongObjectHashMap<>();
- for (Postcode p : postcodes) {
- postcodeMap.put(p.id, p);
- }
-
- vehicles = db.queryReadOnly("SELECT * FROM vehicles", Vehicle.SELECT);
- depotVehicles = HashMultimap.create();
- for (Vehicle v : vehicles) {
- depotVehicles.put(v.depot, v);
- }
-
- hubs = db.queryReadOnly("SELECT * FROM hubs", Hub.SELECT);
- hubMap = new TLongObjectHashMap<>();
- for (Hub h : hubs) {
- hubMap.put(h.id, h);
- }
-
- depots = db.queryReadOnly("SELECT * FROM depots", Depot.SELECT);
- depotMap = new TLongObjectHashMap<>();
- for (Depot d : depots) {
- depotMap.put(d.id, d);
- }
-
- holidays = new HashSet<>();
- db.queryReadOnly("SELECT holiday FROM holidays", SequenceUtils.into(holidays, DB.SELECT_DATEMIDNIGHT));
-
- warehouses = db.queryReadOnly("SELECT * FROM warehouses", Warehouse.SELECT);
- warehouseMap = HashMultimap.create();
- for (Warehouse w : warehouses) {
- warehouseMap.put(w.hub, w);
- }
-
- storages = db.queryReadOnly("SELECT * FROM storage_areas", StorageArea.SELECT);
- areas = HashMultimap.create();
- for (StorageArea s : storages) {
- areas.put(s.warehouse, s);
- }
-
- postcodeClosestDepot = new TLongObjectHashMap<>();
- for (Postcode pc : postcodes) {
- double dist = 0d;
- Depot dmin = null;
- Point pcp = postcodeLocation(pc.code);
- for (Depot d : depots) {
- Point dd = depotLocation(d.id);
- double dist1 = dd.distance(pcp);
-
- if (dmin == null || dist > dist1) {
- dmin = d;
- dist = dist1;
- }
- }
- postcodeClosestDepot.put(pc.id, dmin);
- }
-
- depotClosestHub = new TLongObjectHashMap<>();
- for (Depot d : depots) {
- Hub hmin = null;
- double dist = 0d;
- Point dd = depotLocation(d.id);
- for (Hub h : hubs) {
- Point hp = hubLocation(h.id);
- double dist1 = hp.distance(dd);
- if (hmin == null || dist > dist1) {
- hmin = h;
- dist = dist1;
- }
- }
- depotClosestHub.put(d.id, hmin);
- }
-
- }
- /**
- * Generate.
- * @throws SQLException ingored
- */
- public void run() throws SQLException {
- DateMidnight startDay = new DateMidnight(2013, 7, 1);
- DateMidnight endDay = new DateMidnight(2013, 12, 31);
-
- DateMidnight day = startDay;
-
- while (day.compareTo(endDay) <= 0) {
- if (!holidays.contains(day)) {
- int dow = day.getDayOfWeek();
- if (dow != DateTimeConstants.SATURDAY && dow != DateTimeConstants.SUNDAY) {
- System.out.printf("Day: %s%n", day);
- List<Cons> cons = generate(day);
- saveCons(cons);
-
- db.commit();
- }
- }
-
- day = day.plusDays(1);
- }
- }
- /**
- * Generate a day.
- * @param day the day
- * @throws SQLException ignored
- * @return the generated consignments
- */
- List<Cons> generate(DateMidnight day) throws SQLException {
- List<Cons> r = new ArrayList<>();
- LocalTime lt = new LocalTime(7, 0);
- int dy = day.getDayOfYear();
- int dm = day.getDayOfMonth();
- int dw = day.getDayOfWeek();
- int k = 0;
- for (Postcode pc : postcodes) {
- if (pc.id % 5 != dw - 1) {
- int nf = 0;
- int nh = 0;
- int nq = 0;
- switch ((int)(pc.id % 3)) {
- case 0:
- nf = 1;
- break;
- case 1:
- nh = 1;
- nf = dy % 2 == 0 ? 1 : 0;
- nq = dy % 2 != 0 ? 1 : 0;
- break;
- case 2:
- nh = 2;
- break;
- default:
- }
-
- Postcode dpc = postcodes.get((k + postcodes.size() / 3) % postcodes.size());
-
- Cons cs = new Cons();
- r.add(cs);
- cs.id = ++consId;
- cs.created = day.toDateTime().withTime(lt.getHourOfDay(), lt.getMinuteOfHour(), lt.getSecondOfMinute(), lt.getMillisOfSecond());
- cs.itemCount = nf + nh + nq;
- cs.collectionPostcode = pc.id;
- cs.collectionDepot = postcodeClosestDepot.get(pc.id).id;
- cs.hub = depotClosestHub.get(cs.collectionDepot).id;
- cs.deliveryPostcode = dpc.id;
- cs.deliveryDepot = postcodeClosestDepot.get(dpc.id).id;
-
- int sli = ((dm + k) % 30);
- if (sli == 0) {
- cs.service = ServiceLevel.SPECIAL;
- } else
- if (sli < 5) {
- cs.service = ServiceLevel.STANDARD;
- } else
- if (sli < 9) {
- cs.service = ServiceLevel.PRIORITY;
- } else
- if (sli < 18) {
- cs.service = ServiceLevel.STANDARD;
- } else
- if (sli < 22) {
- cs.service = ServiceLevel.PRIORITY;
- } else {
- cs.service = ServiceLevel.STANDARD;
- }
-
- for (int i = 0; i < nf; i++) {
- ConsItem item = new ConsItem();
- item.consignment = cs;
- item.id = ++itemId;
- item.length = 1;
- item.width = 1;
- item.height = 1;
- cs.items.add(item);
- }
- for (int i = 0; i < nh; i++) {
- ConsItem item = new ConsItem();
- item.consignment = cs;
- item.id = ++itemId;
- item.length = 1;
- item.width = 1;
- item.height = 0.5;
- cs.items.add(item);
- }
- for (int i = 0; i < nq; i++) {
- ConsItem item = new ConsItem();
- item.consignment = cs;
- item.id = ++itemId;
- item.length = 1;
- item.width = 1;
- item.height = 0.25;
- cs.items.add(item);
- }
- }
-
- lt = lt.plusSeconds(15);
- k++;
- }
- return r;
- }
- /**
- * Save the consignments and items.
- * @param seq the sequence
- * @throws SQLException on error
- */
- void saveCons(Iterable<Cons> seq) throws SQLException {
- for (Cons cs : seq) {
- db.update("INSERT IGNORE INTO consignments VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
- cs.id, cs.created, DateTime.class,
- cs.hub, cs.collectionDepot, cs.collectionPostcode,
- cs.deliveryDepot, cs.deliveryPostcode,
- cs.service.ordinal(), cs.itemCount, String.class);
-
- db.update("INSERT IGNORE INTO consignments_history VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
- cs.id, cs.created, DateTime.class,
- cs.hub, cs.collectionDepot, cs.collectionPostcode,
- cs.deliveryDepot, cs.deliveryPostcode,
- cs.service.ordinal(), cs.itemCount, String.class);
-
- for (Item item : cs.items) {
- db.update("INSERT IGNORE INTO items VALUES (?, ?, ?, ?, ?, ?) ",
- item.id, cs.id, String.class, item.width, item.height, item.length);
- db.update("INSERT IGNORE INTO items_history VALUES (?, ?, ?, ?, ?, ?) ",
- item.id, cs.id, String.class, item.width, item.height, item.length);
-
- db.update("INSERT IGNORE INTO events VALUES (?, ?, ?, ?)",
- item.id, cs.id, cs.created, ItemEventType.CREATED.ordinal());
- }
- }
- }
- /**
- * Returns the distance between a postcode and a depot.
- * @param postcode the postcode
- * @param depot the depot
- * @return the distance
- */
- public double postcodeDepotDistance(long postcode, long depot) {
- Point pc = postcodeLocation(postcodeMap.get(postcode).code);
- Point pd = depotLocation(depot);
- return pc.distance(pd);
- }
- /**
- * The distance between a hub and depot.
- * @param depot the depot
- * @param hub the hub
- * @return the distance
- */
- public double depotHubDistance(long depot, long hub) {
- Point pd = depotLocation(depot);
- Point ph = hubLocation(hub);
- return pd.distance(ph);
- }
- /**
- * Complete.
- * @throws SQLException ignored
- */
- public void done() throws SQLException {
-
- }
- }
-}
Added: advance-live-reporter-os/src/eu/advance/logistics/live/reporter/demo/CompareFirst.java
===================================================================
--- advance-live-reporter-os/src/eu/advance/logistics/live/reporter/demo/CompareFirst.java (rev 0)
+++ advance-live-reporter-os/src/eu/advance/logistics/live/reporter/demo/CompareFirst.java 2013-10-02 13:57:00 UTC (rev 323)
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2010-2013 The Advance EU 7th Framework project consortium
+ *
+ * This file is part of Advance.
+ *
+ * Advance is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * Advance is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Advance. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+package eu.advance.logistics.live.reporter.demo;
+
+import hu.akarnokd.reactive4java.base.Pair;
+
+import java.util.Comparator;
+
+import org.joda.time.DateTime;
+
+/**
+ * Compare the first element of a pair.
+ * @author karnokd, 2013.10.02.
+ */
+public class CompareFirst implements Comparator<Pair<DateTime, ?>> {
+ @Override
+ public int compare(Pair<DateTime, ?> o1, Pair<DateTime, ?> o2) {
+ return o1.first.compareTo(o2.first);
+ }
+}
\ No newline at end of file
Added: advance-live-reporter-os/src/eu/advance/logistics/live/reporter/demo/Cons.java
===================================================================
--- advance-live-reporter-os/src/eu/advance/logistics/live/reporter/demo/Cons.java (rev 0)
+++ advance-live-reporter-os/src/eu/advance/logistics/live/reporter/demo/Cons.java 2013-10-02 13:57:00 UTC (rev 323)
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2010-2013 The Advance EU 7th Framework project consortium
+ *
+ * This file is part of Advance.
+ *
+ * Advance is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * Advance is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Advance. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+package eu.advance.logistics.live.reporter.demo;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import eu.advance.logistics.live.reporter.model.Consignment;
+
+/** The created consignment. */
+public class Cons extends Consignment {
+ /** The consignment items. */
+ public final List<ConsItem> items = new ArrayList<>();
+}
\ No newline at end of file
Added: advance-live-reporter-os/src/eu/advance/logistics/live/reporter/demo/ConsItem.java
===================================================================
--- advance-live-reporter-os/src/eu/advance/logistics/live/reporter/demo/ConsItem.java (rev 0)
+++ advance-live-reporter-os/src/eu/advance/logistics/live/reporter/demo/ConsItem.java 2013-10-02 13:57:00 UTC (rev 323)
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2010-2013 The Advance EU 7th Framework project consortium
+ *
+ * This file is part of Advance.
+ *
+ * Advance is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * Advance is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Advance. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+package eu.advance.logistics.live.reporter.demo;
+
+import eu.advance.logistics.live.reporter.model.Item;
+
+/**
+ * The consignment item with back-reference to the consignment itself.
+ * @author karnokd, 2013.10.01.
+ */
+public class ConsItem extends Item {
+ /** The parent consignment. */
+ public Cons consignment;
+}
\ No newline at end of file
Added: advance-live-reporter-os/src/eu/advance/logistics/live/reporter/demo/ConsignmentCreator.java
===================================================================
--- advance-live-reporter-os/src/eu/advance/logistics/live/reporter/demo/ConsignmentCreator.java (rev 0)
+++ advance-live-reporter-os/src/eu/advance/logistics/live/reporter/demo/ConsignmentCreator.java 2013-10-02 13:57:00 UTC (rev 323)
@@ -0,0 +1,387 @@
+/*
+ * Copyright 2010-2013 The Advance EU 7th Framework project consortium
+ *
+ * This file is part of Advance.
+ *
+ * Advance is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * Advance is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Advance. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+package eu.advance.logistics.live.reporter.demo;
+
+import gnu.trove.map.TLongObjectMap;
+import gnu.trove.map.hash.TLongObjectHashMap;
+import hu.akarnokd.utils.database.DB;
+import hu.akarnokd.utils.sequence.SequenceUtils;
+
+import java.awt.Point;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.joda.time.DateMidnight;
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeConstants;
+import org.joda.time.LocalTime;
+
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.Multimap;
+
+import eu.advance.logistics.live.reporter.model.Depot;
+import eu.advance.logistics.live.reporter.model.Hub;
+import eu.advance.logistics.live.reporter.model.Item;
+import eu.advance.logistics.live.reporter.model.LorryPosition;
+import eu.advance.logistics.live.reporter.model.Postcode;
+import eu.advance.logistics.live.reporter.model.ServiceLevel;
+import eu.advance.logistics.live.reporter.model.StorageArea;
+import eu.advance.logistics.live.reporter.model.Vehicle;
+import eu.advance.logistics.live.reporter.model.Warehouse;
+
+/**
+ * Consignment creator.
+ * @author karnokd, 2013.10.01.
+ *
+ */
+public class ConsignmentCreator {
+ /** The database connection. */
+ DB db;
+ /** Field. */
+ private List<Postcode> postcodes;
+ /** Field. */
+ private TLongObjectMap<Postcode> postcodeMap;
+ /** Field. */
+ private List<Vehicle> vehicles;
+ /** Field. */
+ private Multimap<Long, Vehicle> depotVehicles;
+ /** Field. */
+ private List<Hub> hubs;
+ /** Field. */
+ private TLongObjectMap<Hub> hubMap;
+ /** Field. */
+ private List<Depot> depots;
+ /** Field. */
+ private TLongObjectMap<Depot> depotMap;
+ /** Field. */
+ private Set<DateMidnight> holidays;
+ /** Field. */
+ private List<Warehouse> warehouses;
+ /** Field. */
+ private Multimap<Long, Warehouse> warehouseMap;
+ /** Field. */
+ private List<StorageArea> storages;
+ /** Field. */
+ private Multimap<String, StorageArea> areas;
+ /** Field. */
+ private TLongObjectMap<Depot> postcodeClosestDepot;
+ /** Field. */
+ private TLongObjectMap<Hub> depotClosestHub;
+ /** The running consignment id. */
+ private long consId;
+ /** The running item ids. */
+ private long itemId;
+ /** The environment agent. */
+ private EnvironmentAgent env;
+ /**
+ * Constructor, sets the database connection.
+ * @param db the database connection
+ */
+ public ConsignmentCreator(DB db) {
+ this.db = db;
+ }
+ /**
+ * Returns the position of a postcode.
+ * @param postcode the postcode in form 'XA00'
+ * @return the position
+ */
+ static Point postcodeLocation(String postcode) {
+ int c = postcode.charAt(1) - 'A';
+ int n = Integer.parseInt(postcode.substring(2));
+
+ return new Point(n, c * 3);
+ }
+ /**
+ * Initializes the environment.
+ * @throws SQLException ignored
+ */
+ public void init() throws SQLException {
+ postcodes = db.queryReadOnly("SELECT * FROM postcodes", Postcode.SELECT);
+ postcodeMap = new TLongObjectHashMap<>();
+ for (Postcode p : postcodes) {
+ postcodeMap.put(p.id, p);
+ }
+
+ vehicles = db.queryReadOnly("SELECT * FROM vehicles", Vehicle.SELECT);
+ depotVehicles = HashMultimap.create();
+ for (Vehicle v : vehicles) {
+ depotVehicles.put(v.depot, v);
+ }
+
+ hubs = db.queryReadOnly("SELECT * FROM hubs", Hub.SELECT);
+ hubMap = new TLongObjectHashMap<>();
+ for (Hub h : hubs) {
+ hubMap.put(h.id, h);
+ }
+
+ depots = db.queryReadOnly("SELECT * FROM depots", Depot.SELECT);
+ depotMap = new TLongObjectHashMap<>();
+ for (Depot d : depots) {
+ depotMap.put(d.id, d);
+ }
+
+ holidays = new HashSet<>();
+ db.queryReadOnly("SELECT holiday FROM holidays", SequenceUtils.into(holidays, DB.SELECT_DATEMIDNIGHT));
+
+ warehouses = db.queryReadOnly("SELECT * FROM warehouses", Warehouse.SELECT);
+ warehouseMap = HashMultimap.create();
+ for (Warehouse w : warehouses) {
+ warehouseMap.put(w.hub, w);
+ }
+
+ storages = db.queryReadOnly("SELECT * FROM storage_areas", StorageArea.SELECT);
+ areas = HashMultimap.create();
+ for (StorageArea s : storages) {
+ areas.put(s.warehouse, s);
+ }
+
+ postcodeClosestDepot = new TLongObjectHashMap<>();
+ for (Postcode pc : postcodes) {
+ double dist = 0d;
+ Depot dmin = null;
+ Point pcp = postcodeLocation(pc.code);
+ for (Depot d : depots) {
+ Point dd = EnvironmentAgent.depotLocation(d.id);
+ double dist1 = dd.distance(pcp);
+
+ if (dmin == null || dist > dist1) {
+ dmin = d;
+ dist = dist1;
+ }
+ }
+ postcodeClosestDepot.put(pc.id, dmin);
+ }
+
+ depotClosestHub = new TLongObjectHashMap<>();
+ for (Depot d : depots) {
+ Hub hmin = null;
+ double dist = 0d;
+ Point dd = EnvironmentAgent.depotLocation(d.id);
+ for (Hub h : hubs) {
+ Point hp = EnvironmentAgent.hubLocation(h.id);
+ double dist1 = hp.distance(dd);
+ if (hmin == null || dist > dist1) {
+ hmin = h;
+ dist = dist1;
+ }
+ }
+ depotClosestHub.put(d.id, hmin);
+ }
+
+ List<LorryPosition> lorryPositions = db.queryReadOnly("SELECT * FROM lorry_positions", LorryPosition.SELECT);
+
+ // ----------------------------------------------------------
+
+ env = new EnvironmentAgent(db);
+ env.setHubs(hubs);
+ env.setWarehouses(warehouses);
+ env.setStorageAreas(storages);
+ env.setDepots(depots);
+ env.setVehicles(vehicles);
+ env.setLorryPositions(lorryPositions);
+
+ }
+ /**
+ * Generate.
+ * @throws SQLException ingored
+ */
+ public void run() throws SQLException {
+ DateMidnight startDay = new DateMidnight(2013, 7, 1);
+ DateMidnight endDay = new DateMidnight(2013, 12, 31);
+
+ DateMidnight day = startDay;
+
+ while (day.compareTo(endDay) <= 0) {
+ if (!holidays.contains(day)) {
+ int dow = day.getDayOfWeek();
+ if (dow != DateTimeConstants.SATURDAY && dow != DateTimeConstants.SUNDAY) {
+ System.out.printf("Day: %s%n", day);
+ List<Cons> cons = generate(day);
+ DateTime max = saveCons(cons);
+ db.commit();
+
+ if (max != null) {
+ env.consignmentsEnd(max);
+ }
+ }
+ }
+
+ day = day.plusDays(1);
+
+ env.eventLoop();
+ db.commit();
+ }
+ env.eventLoop();
+ db.commit();
+ }
+ /**
+ * Generate a day.
+ * @param day the day
+ * @throws SQLException ignored
+ * @return the generated consignments
+ */
+ List<Cons> generate(DateMidnight day) throws SQLException {
+ List<Cons> r = new ArrayList<>();
+ LocalTime lt = new LocalTime(7, 0);
+ int dy = day.getDayOfYear();
+ int dm = day.getDayOfMonth();
+ int dw = day.getDayOfWeek();
+ int k = 0;
+ for (Postcode pc : postcodes) {
+ if (pc.id % 5 != dw - 1) {
+ int nf = 0;
+ int nh = 0;
+ int nq = 0;
+ switch ((int)(pc.id % 3)) {
+ case 0:
+ nf = 1;
+ break;
+ case 1:
+ nh = 1;
+ nf = dy % 2 == 0 ? 1 : 0;
+ nq = dy % 2 != 0 ? 1 : 0;
+ break;
+ case 2:
+ nh = 2;
+ break;
+ default:
+ }
+
+ Postcode dpc = postcodes.get((k + postcodes.size() / 3) % postcodes.size());
+
+ Cons cs = new Cons();
+ r.add(cs);
+ cs.id = ++consId;
+ cs.created = day.toDateTime().withTime(lt.getHourOfDay(), lt.getMinuteOfHour(), lt.getSecondOfMinute(), lt.getMillisOfSecond());
+ cs.itemCount = nf + nh + nq;
+ cs.collectionPostcode = pc.id;
+ cs.collectionDepot = postcodeClosestDepot.get(pc.id).id;
+ cs.hub = depotClosestHub.get(cs.collectionDepot).id;
+ cs.deliveryPostcode = dpc.id;
+ cs.deliveryDepot = postcodeClosestDepot.get(dpc.id).id;
+ cs.externalId = "C" + cs.id;
+
+ int sli = ((dm + k) % 30);
+ if (sli == 0) {
+ cs.service = ServiceLevel.SPECIAL;
+ } else
+ if (sli < 5) {
+ cs.service = ServiceLevel.STANDARD;
+ } else
+ if (sli < 9) {
+ cs.service = ServiceLevel.PRIORITY;
+ } else
+ if (sli < 18) {
+ cs.service = ServiceLevel.STANDARD;
+ } else
+ if (sli < 22) {
+ cs.service = ServiceLevel.PRIORITY;
+ } else {
+ cs.service = ServiceLevel.STANDARD;
+ }
+
+ for (int i = 0; i < nf; i++) {
+ ConsItem item = new ConsItem();
+ item.consignment = cs;
+ item.id = ++itemId;
+ item.length = 1;
+ item.width = 1;
+ item.height = 1;
+ item.externalId = cs.externalId + "I" + item.id;
+ cs.items.add(item);
+ }
+ for (int i = 0; i < nh; i++) {
+ ConsItem item = new ConsItem();
+ item.consignment = cs;
+ item.id = ++itemId;
+ item.length = 1;
+ item.width = 1;
+ item.height = 0.5;
+ item.externalId = cs.externalId + "I" + item.id;
+ cs.items.add(item);
+ }
+ for (int i = 0; i < nq; i++) {
+ ConsItem item = new ConsItem();
+ item.consignment = cs;
+ item.id = ++itemId;
+ item.length = 1;
+ item.width = 1;
+ item.height = 0.25;
+ item.externalId = cs.externalId + "I" + item.id;
+ cs.items.add(item);
+ }
+
+ for (ConsItem ci : cs.items) {
+ env.newItem(ci);
+ }
+ }
+
+
+
+ lt = lt.plusSeconds(15);
+ k++;
+ }
+ return r;
+ }
+ /**
+ * Save the consignments and items.
+ * @param seq the sequence
+ * @return the latest creation timestamp
+ * @throws SQLException on error
+ */
+ DateTime saveCons(Iterable<Cons> seq) throws SQLException {
+ DateTime max = null;
+ for (Cons cs : seq) {
+ db.update("INSERT IGNORE INTO consignments VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
+ cs.id, cs.created, DateTime.class,
+ cs.hub, cs.collectionDepot, cs.collectionPostcode,
+ cs.deliveryDepot, cs.deliveryPostcode,
+ cs.service.ordinal(), cs.itemCount, cs.externalId);
+
+ db.update("INSERT IGNORE INTO consignments_history VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
+ cs.id, cs.created, DateTime.class,
+ cs.hub, cs.collectionDepot, cs.collectionPostcode,
+ cs.deliveryDepot, cs.deliveryPostcode,
+ cs.service.ordinal(), cs.itemCount, cs.externalId);
+
+ for (Item item : cs.items) {
+ db.update("INSERT IGNORE INTO items VALUES (?, ?, ?, ?, ?, ?) ",
+ item.id, cs.id, item.externalId, item.width, item.height, item.length);
+ db.update("INSERT IGNORE INTO items_history VALUES (?, ?, ?, ?, ?, ?) ",
+ item.id, cs.id, item.externalId, item.width, item.height, item.length);
+ }
+ if (max == null || max.compareTo(cs.created) < 0) {
+ max = cs.created;
+ }
+ }
+ return max;
+ }
+ /**
+ * Complete.
+ * @throws SQLException ignored
+ */
+ public void done() throws SQLException {
+
+ }
+}
\ No newline at end of file
Copied: advance-live-reporter-os/src/eu/advance/logistics/live/reporter/demo/Demo.java (from rev 322, advance-live-reporter-os/src/eu/advance/logistics/live/reporter/db/Demo.java)
===================================================================
--- advance-live-reporter-os/src/eu/advance/logistics/live/reporter/demo/Demo.java (rev 0)
+++ advance-live-reporter-os/src/eu/advance/logistics/live/reporter/demo/Demo.java 2013-10-02 13:57:00 UTC (rev 323)
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2010-2013 The Advance EU 7th Framework project consortium
+ *
+ * This file is part of Advance.
+ *
+ * Advance is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * Advance is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Advance. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+package eu.advance.logistics.live.reporter.demo;
+
+import hu.akarnokd.utils.crypto.BCrypt;
+import hu.akarnokd.utils.database.DB;
+
+import java.sql.SQLException;
+import java.util.Random;
+
+import org.joda.time.DateMidnight;
+
+import eu.advance.logistics.live.reporter.model.UserView;
+
+/**
+ * Prepares the database with demo data.
+ * @author karnokd, 2013.09.24.
+ */
+public final class Demo {
+ /** Demo. */
+ private Demo() { }
+ /**
+ * The demo program.
+ * @param args no arguments
+ * @throws Exception ignored
+ */
+ public static void main(String[] args) throws Exception {
+ try (DB db = DB.connect()) {
+ createMaster(db);
+
+ db.commit();
+
+ ConsignmentCreator cc = new ConsignmentCreator(db);
+ cc.init();
+ cc.run();
+ cc.done();
+
+ db.commit();
+ }
+ }
+ /**
+ * Create the basic hubs and depots.
+ * @param db the database connection
+ * @throws SQLException on error
+ */
+ private static void createMaster(DB db) throws SQLException {
+ // create hubs
+ int nHubs = 2;
+ for (int i = 1; i <= nHubs; i++) {
+ db.update("INSERT IGNORE INTO hubs VALUES (?, ?, ?, ?)", i, "Hub " + i, 1000, 1000);
+ }
+
+ // create depots
+ int nDepots = 20;
+ for (int i = 1; i <= nDepots; i++) {
+ db.update("INSERT IGNORE INTO depots VALUES (?, ?) ", i, "Depot " + i);
+
+ int nVehicles = (int)Math.ceil(5d * i / nDepots);
+
+ for (int j = 1; j <= nVehicles; j++) {
+ db.update("INSERT IGNORE INTO vehicles VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
+ "D" + i + "V" + j, i, Integer.class, Integer.class, 50, 4, 4, 15, 4000
+ );
+ }
+ }
+
+ // create warehouses per hub
+ int nWarehouses = 4;
+ int nLorryPositions = 4;
+
+ Random rnd = new Random(0);
+
+ for (int i = 1; i <= nHubs; i++) {
+ for (int j = 1; j <= nWarehouses; j++) {
+ int x = 500 + (j % 2 == 1 ? -100 : 100);
+ int y = 500 + (j % 2 == 1 ? -150 : 150);
+ int wi = ((i - 1) * nWarehouses + j);
+ db.update("INSERT IGNORE INTO warehouses VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
+ i, "Warehouse " + wi, x, y, 60, 100, 0, rnd.nextInt(5) + 5, "Warehouse " + (wi % 2 == 0 ? wi - 1 : wi + 1));
+
+ int sa = (nDepots / 2) * ((j - 1) / 2);
+ for (int k = 0; k < nDepots / 2; k++) {
+ db.update("INSERT IGNORE INTO storage_areas VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
+ i, "Warehouse " + wi, k % 2, k / 2, sa + k + 1, 20, 1.5, 0, 30
+ );
+ }
+ for (int k = 0; k < nLorryPositions; k++) {
+ int lx = k % 2 == 0 ? 23 : 32;
+ int ly = k / 2 == 0 ? 10 : 60;
+
+ int et = k / 2 == 0 ? 15 : 30;
+ int lt = k / 2 == 0 ? 30 : 15;
+
+ db.update("INSERT IGNORE INTO lorry_positions VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) ",
+ i, "Warehouse " + wi, k, lx, ly, 5, 20, et, lt);
+ }
+ }
+ }
+
+
+ // create hub, warehouse and depot users
+ for (int i = 1; i <= nHubs; i++) {
+ db.update("INSERT IGNORE INTO users (name, hub, depot, admin, default_view, password) VALUES (?, ?, ?, ?, ?, ?)",
+ "admin" + i, 1, Long.class, true, UserView.HUB.ordinal(), BCrypt.hashpw("admin" + i, BCrypt.gensalt()));
+
+ db.update("INSERT IGNORE INTO users (name, hub, depot, admin, default_view, password) VALUES (?, ?, ?, ?, ?, ?)",
+ "hub" + i, 1, Long.class, false, UserView.HUB.ordinal(), BCrypt.hashpw("hub" + i, BCrypt.gensalt()));
+
+ db.update("INSERT IGNORE INTO users (name, hub, depot, admin, default_view, password) VALUES (?, ?, ?, ?, ?, ?)",
+ "warehouse" + i, 1, Long.class, true, UserView.WAREHOUSE.ordinal(), BCrypt.hashpw("warehouse" + i, BCrypt.gensalt()));
+ }
+
+ for (int i = 1; i <= nDepots; i++) {
+ db.update("INSERT IGNORE INTO users (name, hub, depot, admin, default_view, password) VALUES (?, ?, ?, ?, ?, ?)",
+ "depot" + i, 1, i, false, UserView.HUB.ordinal(), BCrypt.hashpw("depot" + i, BCrypt.gensalt()));
+ }
+
+
+ // create holidays
+ int nStartYear = 2013;
+ int nEndYear = 2020;
+ for (int y = nStartYear; y <= nEndYear; y++) {
+ db.update("INSERT IGNORE INTO holidays VALUES (?)", new DateMidnight(y, 1, 1));
+ db.update("INSERT IGNORE INTO holidays VALUES (?)", new DateMidnight(y, 12, 25));
+ db.update("INSERT IGNORE INTO holidays VALUES (?)", new DateMidnight(y, 12, 26));
+ db.update("INSERT IGNORE INTO holidays VALUES (?)", new DateMidnight(y, 12, 31));
+ }
+
+ int nPostcodes = 2000;
+ for (int i = 0; i < nPostcodes; i++) {
+ String pcg = "X" + (char)('A' + (i / 100));
+
+ String pc = String.format("%s%02d", pcg, i % 100);
+
+ db.update("INSERT IGNORE INTO postcodes VALUES (?, ?, ?) ",
+ i + 1, pc, pcg);
+ }
+ }
+}
Added: advance-live-reporter-os/src/eu/advance/logistics/live/reporter/demo/DepotAgent.java
===================================================================
--- advance-live-reporter-os/src/eu/advance/logistics/live/reporter/demo/DepotAgent.java (rev 0)
+++ advance-live-reporter-os/src/eu/advance/logistics/live/reporter/demo/DepotAgent.java 2013-10-02 13:57:00 UTC (rev 323)
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2010-2013 The Advance EU 7th Framework project consortium
+ *
+ * This file is part of Advance.
+ *
+ * Advance is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * Advance is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Advance. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+package eu.advance.logistics.live.reporter.demo;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.joda.time.DateTime;
+
+import eu.advance.logistics.live.reporter.model.ItemEventType;
+
+/**
+ * A depot manager "agent".
+ * @author karnokd, 2013.10.01.
+ *
+ */
+public class DepotAgent {
+ /** Depot identifier. */
+ public long id;
+ /** The items to deliver. */
+ public final List<ConsItem> toDeliver = new ArrayList<>();
+ /** The list of own vehicles. */
+ public final List<VehicleAgent> vehicles = new ArrayList<>();
+ /** The vehicles on site. */
+ public final List<VehicleAgent> onSite = new ArrayList<>();
+ /** The environment. */
+ private EnvironmentAgent env;
+ /**
+ * Constructor, sets the environment.
+ * @param env the environment
+ */
+ public DepotAgent(EnvironmentAgent env) {
+ this.env = env;
+ }
+ /**
+ * Item arrived from the collection postcode.
+ * @param now the current time
+ * @param item the item
+ */
+ public void itemArrived(DateTime now, ConsItem item) {
+ toDeliver.add(item);
+ checkLoadVehicle(now);
+ }
+ /**
+ * Vehicle arrived at the depot.
+ * @param now the arrival time
+ * @param va the vehicle
+ */
+ public void vehicleArrived(DateTime now, VehicleAgent va) {
+ for (ConsItem item : va.contents) {
+ env.event(item.id, item.consignmentId, now, ItemEventType.DESTINATION_SCAN);
+ }
+ va.contents.clear();
+ va.targetHub = null;
+ va.atDepot = true;
+ onSite.add(va);
+ checkLoadVehicle(now);
+ }
+ /**
+ * Check if vehicles can be loaded.
+ * @param now the current time
+ */
+ public void checkLoadVehicle(DateTime now) {
+ if (!onSite.isEmpty()) {
+ for (ConsItem ci : new ArrayList<>(toDeliver)) {
+ List<VehicleAgent> vas = new ArrayList<>(onSite);
+ Collections.sort(vas, VehicleAgent.CAPACITY);
+ for (VehicleAgent va : vas) {
+ if (va.tryLoadInDepot(now, ci)) {
+ toDeliver.remove(ci);
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
Added: advance-live-reporter-os/src/eu/advance/logistics/live/reporter/demo/EnvironmentAgent.java
===================================================================
--- advance-live-reporter-os/src/eu/advance/logistics/live/reporter/demo/EnvironmentAgent.java (rev 0)
+++ advance-live-reporter-os/src/eu/advance/logistics/live/reporter/demo/EnvironmentAgent.java 2013-10-02 13:57:00 UTC (rev 323)
@@ -0,0 +1,378 @@
+/*
+ * Copyright 2010-2013 The Advance EU 7th Framework project consortium
+ *
+ * This file is part of Advance.
+ *
+ * Advance is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * Advance is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Advance. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+package eu.advance.logistics.live.reporter.demo;
+
+import eu.advance.logistics.live.reporter.model.Depot;
+import eu.advance.logistics.live.reporter.model.Hub;
+import eu.advance.logistics.live.reporter.model.ItemEventType;
+import eu.advance.logistics.live.reporter.model.LorryPosition;
+import eu.advance.logistics.live.reporter.model.ScanType;
+import eu.advance.logistics.live.reporter.model.StorageArea;
+import eu.advance.logistics.live.reporter.model.Vehicle;
+import eu.advance.logistics.live.reporter.model.Warehouse;
+import gnu.trove.map.TLongObjectMap;
+import gnu.trove.map.hash.TLongObjectHashMap;
+import hu.akarnokd.reactive4java.base.Action0;
+import hu.akarnokd.reactive4java.base.Pair;
+import hu.akarnokd.utils.database.DB;
+
+import java.awt.Point;
+import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.PriorityQueue;
+
+import org.joda.time.DateTime;
+
+/**
+ * The base environment for the agents.
+ * @author karnokd, 2013.10.02.
+ */
+public class EnvironmentAgent {
+ /** The database connection. */
+ protected final DB db;
+ /** The map of depots. */
+ private final TLongObjectMap<DepotAgent> depotAgents = new TLongObjectHashMap<>();
+ /** The map of vehicles. */
+ private final Map<String, VehicleAgent> vehicleAgents = new HashMap<>();
+ /** The map of warehouses. */
+ private final Map<String, WarehouseAgent> warehouseAgents = new HashMap<>();
+ /** The map of hub agents. */
+ private final TLongObjectMap<HubAgent> hubAgents = new TLongObjectHashMap<>();
+ /** The event sequence. */
+ private final PriorityQueue<Pair<DateTime, Action0>> events = new PriorityQueue<>(256, new CompareFirst());
+ /**
+ * Constructor.
+ * @param db the database
+ */
+ public EnvironmentAgent(DB db) {
+ this.db = db;
+ }
+ /**
+ * The event loop.
+ */
+ public void eventLoop() {
+ while (!events.isEmpty()) {
+ Pair<DateTime, Action0> e = events.remove();
+ e.second.invoke();
+ }
+ }
+ /**
+ * Add a new event to the queue.
+ * @param timestamp the timestamp
+ * @param action the action
+ */
+ public void add(DateTime timestamp, Action0 action) {
+ events.add(Pair.of(timestamp, action));
+ }
+ /**
+ * Create hub agents.
+ * @param hubs the sequence of hubs
+ */
+ public void setHubs(Iterable<Hub> hubs) {
+ hubAgents.clear();
+ for (Hub h : hubs) {
+ HubAgent ha = new HubAgent(this);
+ ha.id = h.id;
+ hubAgents.put(ha.id, ha);
+ }
+ }
+ /**
+ * Create warehouse agents for hubs.
+ * @param warehouses the warehouses
+ */
+ public void setWarehouses(Iterable<Warehouse> warehouses) {
+ warehouseAgents.clear();
+ for (Warehouse wh : warehouses) {
+ HubAgent ha = hubAgents.get(wh.hub);
+
+ WarehouseAgent wa = new WarehouseAgent(this);
+ wa.hub = wh.hub;
+ wa.warehouse = wh.warehouse;
+
+ ha.warehouses.add(wa);
+
+ warehouseAgents.put(wa.warehouse, wa);
+ }
+ }
+ /**
+ * Set the storage areas insode warehouses.
+ * @param storages the storage areas
+ */
+ public void setStorageAreas(Iterable<StorageArea> storages) {
+ for (StorageArea sa : storages) {
+ WarehouseAgent wa = warehouseAgents.get(sa.warehouse);
+
+ wa.depots.add(sa.depot);
+ }
+ }
+ /**
+ * Create the depot agents.
+ * @param depots the depots
+ */
+ public void setDepots(Iterable<Depot> depots) {
+ depotAgents.clear();
+ for (Depot d : depots) {
+ DepotAgent da = new DepotAgent(this);
+ da.id = d.id;
+
+ depotAgents.put(da.id, da);
+ }
+
+ }
+ /**
+ * Create the vehicle agents.
+ * @param vehicles the vehicle
+ */
+ public void setVehicles(Iterable<Vehicle> vehicles) {
+ vehicleAgents.clear();
+ for (Vehicle v : vehicles) {
+ DepotAgent da = depotAgents.get(v.depot);
+
+ VehicleAgent va = new VehicleAgent(this);
+ va.id = v.vehicleId;
+ va.depot = v.depot;
+ va.capacity = v.capacity;
+
+ da.onSite.add(va);
+ da.vehicles.add(va);
+
+ vehicleAgents.put(va.id, va);
+ }
+ }
+ /**
+ * Set the lorry positions in warehouses.
+ * @param lorryPositions the lorry position sequence
+ */
+ public void setLorryPositions(Iterable<LorryPosition> lorryPositions) {
+ for (LorryPosition lp : lorryPositions) {
+ WarehouseAgent wa = warehouseAgents.get(lp.warehouse);
+ wa.positions.add(lp);
+ }
+ }
+ /**
+ * Stores an event for a particulare item.
+ * @param itemId the item identifier
+ * @param consignmentId the parent consignment id
+ * @param timestamp the event timestamp
+ * @param event the event
+ */
+ public void event(long itemId, long consignmentId, DateTime timestamp, ItemEventType event) {
+ try {
+ db.update("INSERT INGORE INTO events VALUES (?, ?, ?, ?)", itemId, consignmentId, timestamp, event.ordinal());
+ } catch (SQLException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+ /**
+ * Returns the depot position.
+ * @param depot the depot
+ * @return the
+ */
+ static Point depotLocation(long depot) {
+ int x = (int)(16 + 16 * ((depot - 1) % 5));
+ int y = (int)(10 + 10 * ((depot - 1) / 5));
+
+ return new Point(x, y);
+ }
+ /**
+ * Returns the position of the hub.
+ * @param hub the hub id
+ * @return the position
+ */
+ static Point hubLocation(long hub) {
+ return new Point((int)(hub * 33), 30);
+ }
+ /**
+ * Returns the position of a postcode.
+ * @param postcode the postcode in form 'XA00'
+ * @return the position
+ */
+ static Point postcodeLocation(long postcode) {
+ int c = (int)((postcode - 1) / 100);
+ int n = (int)((postcode - 1) % 100);
+
+ return new Point(n, c * 3);
+ }
+ /**
+ * Returns the distance between a postcode and a depot.
+ * @param postcode the postcode
+ * @param depot the depot
+ * @return the distance
+ */
+ public double postcodeDepotDistance(long postcode, long depot) {
+ Point pc = postcodeLocation(postcode);
+ Point pd = depotLocation(depot);
+ return pc.distance(pd);
+ }
+ /**
+ * The distance between a hub and depot.
+ * @param depot the depot
+ * @param hub the hub
+ * @return the distance
+ */
+ public double depotHubDistance(long depot, long hub) {
+ Point pd = depotLocation(depot);
+ Point ph = hubLocation(hub);
+ return pd.distance(ph);
+ }
+ /**
+ * Computes the arrival time of an item travelling from the postcode to the depot.
+ * @param now the current time
+ * @param postcode the postcode
+ * @param depot the depot
+ * @return the arrival time
+ */
+ public DateTime postcodeDepotTravel(DateTime now, long postcode, long depot) {
+ double d = postcodeDepotDistance(postcode, depot) * 60 * 1.5;
+
+ return now.plusSeconds((int)d);
+ }
+ /**
+ * Computes the arrival time of a vehicle, from depot to hub.
+ * @param now the current time
+ * @param depot the depot
+ * @param hub the hub
+ * @return the arrival time
+ */
+ public DateTime depotHubTravel(DateTime now, long depot, long hub) {
+ double d = depotHubDistance(depot, hub) * 60 * 1.5;
+
+ return now.plusSeconds((int)d);
+ }
+ /**
+ * Add a new item.
+ * @param item the item
+ */
+ public void newItem(final ConsItem item) {
+
+ event(item.id, item.consignmentId, item.consignment.created, ItemEventType.CREATED);
+
+ final DateTime depotArrive = postcodeDepotTravel(item.consignment.created, item.consignment.collectionPostcode, item.consignment.collectionDepot);
+
+ final DepotAgent da = depotAgents.get(item.consignment.collectionDepot);
+
+ add(depotArrive, new Action0() {
+ @Override
+ public void invoke() {
+ da.itemArrived(depotArrive, item);
+ }
+ });
+ }
+ /**
+ * Register a collection scan.
+ * @param vehicleId the vehicle identifier
+ * @param when the scan time
+ * @param item the item
+ */
+ public void collectionScan(String vehicleId, DateTime when, ConsItem item) {
+ event(item.id, item.consignmentId, when, ItemEventType.SOURCE_SCAN);
+
+ try {
+ db.update("INSERT IGNORE INTO scans VALUES (?, ?, ?, ?, ?, ?, ?)",
+ item.consignmentId, item.id, ScanType.SOURCE.ordinal(),
+ item.consignment.collectionDepot, true, when, vehicleId);
+
+ db.update("INSERT IGNORE INTO scans_history VALUES (?, ?, ?, ?, ?, ?, ?)",
+ item.consignmentId, item.id, ScanType.SOURCE.ordinal(),
+ item.consignment.collectionDepot, true, when, vehicleId);
+ } catch (SQLException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+ /**
+ * Declare a pallet on a vehicle.
+ * @param vehicleId the vehicle identifier
+ * @param when the time of the declaration
+ * @param externalItemId the item identifier
+ */
+ public void declare(String vehicleId, DateTime when, String externalItemId) {
+ int iidx = externalItemId.indexOf("I");
+ long consId = Long.parseLong(externalItemId.substring(1, iidx));
+// long itemId = Long.parseLong(externalItemId.substring(iidx + 1));
+
+ try {
+ db.update("INSERT IGNORE INTO vehicle_declared VALUES (?, ?, ?)", vehicleId, when, externalItemId);
+ db.update("UPDATE consignments SET declared = ? WHERE id = ?", when, consId);
+ db.update("UPDATE consignments_history SET declared = ? WHERE id = ?", when, consId);
+ } catch (SQLException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+ /**
+ * Vehicle arrived at hub.
+ * @param now the current time
+ * @param hub the hub
+ * @param va the vehicle
+ */
+ public void hubArrive(final DateTime now, final long hub, final VehicleAgent va) {
+ va.sessionId = hub + "_" + now.toString("yyyyMMdd'_'HHmmss") + "_" + va.id;
+ va.atHub = true;
+
+ for (ConsItem ci : va.contents) {
+ event(ci.id, ci.consignmentId, now, ItemEventType.HUB_ARRIVE);
+ }
+
+ HubAgent ha = hubAgents.get(va.targetHub);
+ ha.vehiclesOnSite.add(va);
+ ha.loadUnload(now);
+ }
+ /**
+ * Register the contents of the vehicle entering/leaving its warehouse.
+ * @param va the vehicle
+ * @param now the current time
+ * @param enter is enter?
+ */
+ public void warehouseScan(VehicleAgent va, DateTime now, boolean enter) {
+ try {
+ long sid = db.insertAuto("INSERT INTO vehicle_scan (session_id, scan_timestamp, warehouse, entry) VALUES (?, ?, ?, ?)",
+ va.sessionId, now, va.warehouse, enter
+ );
+ for (ConsItem ci : va.contents) {
+ event(ci.id, ci.consignmentId, now, ItemEventType.WAREHOUSE_ENTER);
+ db.update("INSERT INTO vehicle_items VALUES (?, ?) ", sid, ci.externalId);
+
+ ScanType st = enter ? ScanType.WAREHOUSE_ENTER : ScanType.WAREHOUSE_LEAVE;
+
+ db.update("INSERT IGNORE INTO scans VALUES (?, ?, ?, ?, ?, ?)",
+ ci.consignmentId, ci.id, st,
+ va.targetHub + " " + va.warehouse, now, va.id);
+
+ db.update("INSERT IGNORE INTO scans_history VALUES (?, ?, ?, ?, ?, ?)",
+ ci.consignmentId, ci.id, st,
+ va.targetHub + " " + va.warehouse, now, va.id);
+
+ }
+ } catch (SQLException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+ /**
+ * Indicate that no more consignments will appear on the given day.
+ * @param now the current time
+ */
+ public void consignmentsEnd(DateTime now) {
+ // TODO
+ for (DepotAgent da : depotAgents.valueCollection()) {
+
+ }
+ }
+}
Added: advance-live-reporter-os/src/eu/advance/logistics/live/reporter/demo/HubAgent.java
===================================================================
--- advance-live-reporter-os/src/eu/advance/logistics/live/reporter/demo/HubAgent.java (rev 0)
+++ advance-live-reporter-os/src/eu/advance/logistics/live/reporter/demo/HubAgent.java 2013-10-02 13:57:00 UTC (rev 323)
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2010-2013 The Advance EU 7th Framework project consortium
+ *
+ * This file is part of Advance.
+ *
+ * Advance is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * Advance is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Advance. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+package eu.advance.logistics.live.reporter.demo;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.joda.time.DateTime;
+
+/**
+ * The hub agent.
+ * @author karnokd, 2013.10.01.
+ */
+publi...
[truncated message content] |