diff --git a/Code Snippets/dataSim.py b/Code Snippets/dataSim.py new file mode 100644 index 0000000..d1579e6 --- /dev/null +++ b/Code Snippets/dataSim.py @@ -0,0 +1,133 @@ +#!/usr/bin/env python3 +""" +mqtt_counter_publish.py +----------------------- + +* Uses `paho.mqtt.client` to connect to a broker. +* Publishes a list of *static* payloads to a topic. +* Measures bytes sent/received by the **process** with `psutil`. +* Prints a neat summary at the end. + +""" + +import os +import json +import time +import random +import psutil +import paho.mqtt.client as mqtt + +# ------------------------------------------------------------------ +# Helper: return write_bytes / read_bytes of the current process +# ------------------------------------------------------------------ +def get_io_counters(): + """Return (write_bytes, read_bytes) for the current process.""" + proc = psutil.Process(os.getpid()) + io = proc.io_counters() # .write_bytes, .read_bytes + return io.write_bytes, io.read_bytes #io.write_chars, io.read_chars #io.write_bytes, io.read_bytes + +def print_io_delta(start, end): + """Print the difference between two (write, read) tuples.""" + sent = end[0] - start[0] + recv = end[1] - start[1] + print(f"\nΔ sent: {sent:,} bytes") + print(f"Δ received: {recv:,} bytes\n") + +# ------------------------------------------------------------------ +# MQTT callbacks (minimal – we don't care about incoming messages) +# ------------------------------------------------------------------ +def on_connect(client, userdata, flags, rc): + if rc == 0: + print("✅ Connected to broker") + else: + print(f"❌ Connect failed (rc={rc})") + +# ------------------------------------------------------------------ +# Publish static payloads +# ------------------------------------------------------------------ +def publish_static_payloads(client, topic, payloads, delay=0.1): + """ + Publish each payload in `payloads` to `topic`. + `delay` (seconds) can be used to throttle the rate. + """ + for i, payload in enumerate(payloads, 1): + result = client.publish(topic, json.dumps(payload)) + # Wait for the network loop to actually send it + client.loop(timeout=0.1) + if result.rc != mqtt.MQTT_ERR_SUCCESS: + print(f"⚠️ Publish {i} failed with rc={result.rc}") + else: + print(f"→ Sent msg #{i} ({len(json.dumps(payload))} bytes)") + time.sleep(delay) + +# ------------------------------------------------------------------ +# Main routine +# ------------------------------------------------------------------ +def main(): + broker = "hp.henrypump.cloud" # change if needed + port = 1883 # default MQTT + topic = "v1/devices/me/telemetry" + + # Static payloads – feel free to replace with your own data + payloads = [] + now = time.time() * 1000 + for x in range(25): + values = {} + for y in range(20): + values[f"my_telemetry_{x+y}"] = random.random() + payloads.append({"ts": now, "values": values}) + + payloads = [{"test1k": "A" * 1024}] + # ------------------------------------------------------------------ + # Create MQTT client, connect + # ------------------------------------------------------------------ + client = mqtt.Client() + client.username_pw_set("e5xv3wfi1oa44ty2ydv2") + client.on_connect = on_connect + client.connect(broker, port, keepalive=60) + + # ------------------------------------------------------------- + # 1️⃣ Capture baseline I/O counters **before** any traffic + # ------------------------------------------------------------- + baseline = get_io_counters() + print("\n📊 Baseline I/O counters:") + print(f" Written: {baseline[0]:,} bytes") + print(f" Read: {baseline[1]:,} bytes") + + # ------------------------------------------------------------- + # 2️⃣ Start network loop in a background thread + # ------------------------------------------------------------- + client.loop_start() + + # ------------------------------------------------------------- + # 3️⃣ Publish the static payloads + # ------------------------------------------------------------- + print("\n📤 Publishing static payloads …") + for _ in range(1): + publish_static_payloads(client, topic, payloads, delay=0.2) + + # Give the broker a moment to ack / reply (if any) + time.sleep(10) + + # ------------------------------------------------------------- + # 4️⃣ Capture I/O counters **after** traffic + # ------------------------------------------------------------- + final = get_io_counters() + print("\n📊 Final I/O counters:") + print(f" Written: {final[0]:,} bytes") + print(f" Read: {final[1]:,} bytes") + + # ------------------------------------------------------------- + # 5️⃣ Report the delta + # ------------------------------------------------------------- + print_io_delta(baseline, final) + + # ------------------------------------------------------------- + # Clean‑up + # ------------------------------------------------------------- + client.loop_stop() + client.disconnect() + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/Code Snippets/data_estimation_calculator.xlsx b/Code Snippets/data_estimation_calculator.xlsx new file mode 100644 index 0000000..395188b Binary files /dev/null and b/Code Snippets/data_estimation_calculator.xlsx differ diff --git a/Code Snippets/network_usage_per_process.py b/Code Snippets/network_usage_per_process.py new file mode 100644 index 0000000..1a82dc8 --- /dev/null +++ b/Code Snippets/network_usage_per_process.py @@ -0,0 +1,153 @@ +from scapy.all import * +import psutil +from collections import defaultdict +import os, time +from datetime import datetime +from threading import Thread +import pandas as pd + +# get the all network adapter's MAC addresses +all_macs = {iface.mac for iface in ifaces.values()} +# A dictionary to map each connection to its correponding process ID (PID) +connection2pid = {} +# A dictionary to map each process ID (PID) to total Upload (0) and Download (1) traffic +pid2traffic = defaultdict(lambda: [0, 0]) +# the global Pandas DataFrame that's used to track previous traffic stats +global_df = None +# global boolean for status of the program +is_program_running = True + +def get_size(bytes): + """ + Returns size of bytes in a nice format + """ + for unit in ['', 'K', 'M', 'G', 'T', 'P']: + if bytes < 1024: + return f"{bytes:.2f}{unit}B" + bytes /= 1024 + + +def process_packet(packet): + global pid2traffic + try: + # get the packet source & destination IP addresses and ports + packet_connection = (packet.sport, packet.dport) + except (AttributeError, IndexError): + # sometimes the packet does not have TCP/UDP layers, we just ignore these packets + pass + else: + # get the PID responsible for this connection from our `connection2pid` global dictionary + packet_pid = connection2pid.get(packet_connection) + if packet_pid: + if packet.src in all_macs: + # the source MAC address of the packet is our MAC address + # so it's an outgoing packet, meaning it's upload + pid2traffic[packet_pid][0] += len(packet) + else: + # incoming packet, download + pid2traffic[packet_pid][1] += len(packet) + + +def get_connections(): + """A function that keeps listening for connections on this machine + and adds them to `connection2pid` global variable""" + global connection2pid + while is_program_running: + # using psutil, we can grab each connection's source and destination ports + # and their process ID + for c in psutil.net_connections(): + if c.laddr and c.raddr and c.pid: + # if local address, remote address and PID are in the connection + # add them to our global dictionary + connection2pid[(c.laddr.port, c.raddr.port)] = c.pid + connection2pid[(c.raddr.port, c.laddr.port)] = c.pid + # sleep for a second, feel free to adjust this + time.sleep(1) + + +def print_pid2traffic(): + global global_df + # initialize the list of processes + processes = [] + for pid, traffic in pid2traffic.items(): + # `pid` is an integer that represents the process ID + # `traffic` is a list of two values: total Upload and Download size in bytes + try: + # get the process object from psutil + p = psutil.Process(pid) + except psutil.NoSuchProcess: + # if process is not found, simply continue to the next PID for now + continue + # get the name of the process, such as chrome.exe, etc. + name = p.name() + # get the time the process was spawned + try: + create_time = datetime.fromtimestamp(p.create_time()) + except OSError: + # system processes, using boot time instead + create_time = datetime.fromtimestamp(psutil.boot_time()) + # construct our dictionary that stores process info + process = { + "pid": pid, "name": name, "create_time": create_time, "Upload": traffic[0], + "Download": traffic[1], + } + try: + # calculate the upload and download speeds by simply subtracting the old stats from the new stats + process["Upload Speed"] = traffic[0] - global_df.at[pid, "Upload"] + process["Download Speed"] = traffic[1] - global_df.at[pid, "Download"] + except (KeyError, AttributeError): + # If it's the first time running this function, then the speed is the current traffic + # You can think of it as if old traffic is 0 + process["Upload Speed"] = traffic[0] + process["Download Speed"] = traffic[1] + # append the process to our processes list + processes.append(process) + # construct our Pandas DataFrame + df = pd.DataFrame(processes) + try: + # set the PID as the index of the dataframe + df = df.set_index("pid") + # sort by column, feel free to edit this column + df.sort_values("Download", inplace=True, ascending=False) + except KeyError as e: + # when dataframe is empty + pass + # make another copy of the dataframe just for fancy printing + printing_df = df.copy() + try: + # apply the function get_size to scale the stats like '532.6KB/s', etc. + printing_df["Download"] = printing_df["Download"].apply(get_size) + printing_df["Upload"] = printing_df["Upload"].apply(get_size) + printing_df["Download Speed"] = printing_df["Download Speed"].apply(get_size).apply(lambda s: f"{s}/s") + printing_df["Upload Speed"] = printing_df["Upload Speed"].apply(get_size).apply(lambda s: f"{s}/s") + except KeyError as e: + # when dataframe is empty again + pass + # clear the screen based on your OS + os.system("cls") if "nt" in os.name else os.system("clear") + # print our dataframe + print(printing_df.to_string()) + # update the global df to our dataframe + global_df = df + + +def print_stats(): + """Simple function that keeps printing the stats""" + while is_program_running: + time.sleep(1) + print_pid2traffic() + + + +if __name__ == "__main__": + # start the printing thread + printing_thread = Thread(target=print_stats) + printing_thread.start() + # start the get_connections() function to update the current connections of this machine + connections_thread = Thread(target=get_connections) + connections_thread.start() + # start sniffing + print("Started sniffing") + sniff(prn=process_packet, store=False) + # setting the global variable to False to exit the program + is_program_running = False \ No newline at end of file diff --git a/Code Snippets/rrig_kmz/breakout_kml.py b/Code Snippets/rrig_kmz/breakout_kml.py new file mode 100644 index 0000000..0a8e7f7 --- /dev/null +++ b/Code Snippets/rrig_kmz/breakout_kml.py @@ -0,0 +1,142 @@ +#!/usr/bin/env python3 +""" +KML coordinate extractor +------------------------ + +* Every element → list of [lat, lon] pairs, written to *output_polygons*. +* Every element → list of [lat, lon] pairs, written to *output_linestrings*. +* Every that contains a and a → “Marker Name: lat, lon” + written to *output_markers*. + +The coordinates in a KML file are stored as `lon,lat[,alt]`. +The script converts them to `lat,lon` because that’s the format you asked for. +""" + +import xml.etree.ElementTree as ET +import sys +from pathlib import Path + +# ---------------------------------------------------------------------- +# Helpers +# ---------------------------------------------------------------------- +def parse_kml(file_path: Path) -> ET.ElementTree: + """Parse the KML file; exit with a message on failure.""" + try: + return ET.parse(file_path) + except ET.ParseError as exc: + print(f"ERROR: Failed to parse {file_path}: {exc}", file=sys.stderr) + sys.exit(1) + +def _lon_lat_to_list(coord_str: str) -> list[list[float]]: + """ + Convert a KML coordinate string (lon,lat[,alt] …) into a list of [lat, lon]. + Ignores malformed entries. + """ + coords = [] + for pair in coord_str.strip().split(): + parts = pair.split(',') + if len(parts) < 2: + continue + lon, lat = float(parts[0]), float(parts[1]) + coords.append([lat, lon]) + return coords + +# ---------------------------------------------------------------------- +# Main extraction routine +# ---------------------------------------------------------------------- +def extract_kml( + kml_file: Path, + out_polygons: Path, + out_linestrings: Path, + out_markers: Path, +) -> None: + tree = parse_kml(kml_file) + root = tree.getroot() + + # Namespace handling (most KML files use the same namespace) + ns = {'kml': root.tag.split('}')[0].strip('{')} + + # ------------------------------------------------------------------ + # 1) Polygons + # ------------------------------------------------------------------ + polygons = [] # List[ List[ [lat, lon] ] ] + for poly in root.findall('.//kml:Polygon', ns): + coord_el = poly.find('.//kml:coordinates', ns) + if coord_el is None or not coord_el.text: + continue + polygons.append(_lon_lat_to_list(coord_el.text)) + + # Write polygons + with out_polygons.open('w', encoding='utf-8') as fp: + for i, poly in enumerate(polygons, start=1): + fp.write(f"Polygon {i}:\n") + fp.write(str(poly) + "\n\n") + + # ------------------------------------------------------------------ + # 2) LineStrings + # ------------------------------------------------------------------ + linestrings = [] # List[ List[ [lat, lon] ] ] + for ls in root.findall('.//kml:LineString', ns): + coord_el = ls.find('.//kml:coordinates', ns) + if coord_el is None or not coord_el.text: + continue + linestrings.append(_lon_lat_to_list(coord_el.text)) + + # Write LineStrings + with out_linestrings.open('w', encoding='utf-8') as fp: + for i, ls in enumerate(linestrings, start=1): + fp.write(f"LineString {i}:\n") + fp.write(str(ls) + "\n\n") + + # ------------------------------------------------------------------ + # 3) Markers (Point placemarks with a name) + # ------------------------------------------------------------------ + markers = [] # List[ (name, [lat, lon]) ] + for pm in root.findall('.//kml:Placemark', ns): + name_el = pm.find('kml:name', ns) + point_el = pm.find('.//kml:Point/kml:coordinates', ns) + if name_el is None or point_el is None: + continue + + name = name_el.text.strip() + coord_list = _lon_lat_to_list(point_el.text) + if not coord_list: + continue + markers.append((name, coord_list[0])) # a point has exactly one pair + + # Write markers + with out_markers.open('w', encoding='utf-8') as fp: + for name, (lat, lon) in markers: + fp.write(f"{name}: {lat}, {lon}\n") + + # ------------------------------------------------------------------ + # Summary + # ------------------------------------------------------------------ + print(f"Polygons written to: {out_polygons}") + print(f"LineStrings written to: {out_linestrings}") + print(f"Markers written to: {out_markers}") + +# ---------------------------------------------------------------------- +# Entry‑point +# ---------------------------------------------------------------------- +def main() -> None: + if len(sys.argv) != 5: + print( + "Usage: python breakout_kml.py " + " " + ) + sys.exit(1) + + input_file = Path(sys.argv[1]).expanduser().resolve() + out_polygons = Path(sys.argv[2]).expanduser().resolve() + out_linestrings = Path(sys.argv[3]).expanduser().resolve() + out_markers = Path(sys.argv[4]).expanduser().resolve() + + if not input_file.exists(): + print(f"ERROR: Input file not found: {input_file}", file=sys.stderr) + sys.exit(1) + + extract_kml(input_file, out_polygons, out_linestrings, out_markers) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/Code Snippets/rrig_kmz/kmz/Node C Monahans Booster Station.kmz b/Code Snippets/rrig_kmz/kmz/Node C Monahans Booster Station.kmz new file mode 100644 index 0000000..f2f632e Binary files /dev/null and b/Code Snippets/rrig_kmz/kmz/Node C Monahans Booster Station.kmz differ diff --git a/Code Snippets/rrig_kmz/kmz/Node D 10 to 12 Transition - Wadell Valve.kmz b/Code Snippets/rrig_kmz/kmz/Node D 10 to 12 Transition - Wadell Valve.kmz new file mode 100644 index 0000000..b8a5d32 Binary files /dev/null and b/Code Snippets/rrig_kmz/kmz/Node D 10 to 12 Transition - Wadell Valve.kmz differ diff --git a/Code Snippets/rrig_kmz/kmz/Node F US Silica.kmz b/Code Snippets/rrig_kmz/kmz/Node F US Silica.kmz new file mode 100644 index 0000000..ce6bb92 Binary files /dev/null and b/Code Snippets/rrig_kmz/kmz/Node F US Silica.kmz differ diff --git a/Code Snippets/rrig_kmz/kmz/Node X Cipher Interconnect.kmz b/Code Snippets/rrig_kmz/kmz/Node X Cipher Interconnect.kmz new file mode 100644 index 0000000..cfcd9a4 Binary files /dev/null and b/Code Snippets/rrig_kmz/kmz/Node X Cipher Interconnect.kmz differ diff --git a/Code Snippets/rrig_kmz/kmz/Original - Rig PL wilth existing Azul PL.kmz b/Code Snippets/rrig_kmz/kmz/Original - Rig PL wilth existing Azul PL.kmz new file mode 100644 index 0000000..253cd62 Binary files /dev/null and b/Code Snippets/rrig_kmz/kmz/Original - Rig PL wilth existing Azul PL.kmz differ diff --git a/Code Snippets/rrig_kmz/kmz/RRIG Water Pump Station.kmz b/Code Snippets/rrig_kmz/kmz/RRIG Water Pump Station.kmz new file mode 100644 index 0000000..a0a8e8b Binary files /dev/null and b/Code Snippets/rrig_kmz/kmz/RRIG Water Pump Station.kmz differ diff --git a/Code Snippets/rrig_kmz/kmz_combine.py b/Code Snippets/rrig_kmz/kmz_combine.py new file mode 100644 index 0000000..3c7777a --- /dev/null +++ b/Code Snippets/rrig_kmz/kmz_combine.py @@ -0,0 +1,120 @@ +#!/usr/bin/env python3 +""" +combine_kmz_to_kml.py + +Combine all KMZ files in a folder into a single KML file. + +Usage: + python combine_kmz_to_kml.py + +Example: + python combine_kmz_to_kml.py ./kmz_files all_points.kml +""" + +import os +import sys +import zipfile +import xml.etree.ElementTree as ET +from pathlib import Path +from typing import List + +# ------------------------------------------------------------ +# Helper functions +# ------------------------------------------------------------ + +def find_kmz_files(folder: Path) -> List[Path]: + """Return a list of .kmz files in the given folder (non‑recursive).""" + return list(folder.rglob("*.kmz")) + +def extract_kml_from_kmz(kmz_path: Path) -> ET.ElementTree: + """ + Extract the first KML file found inside a KMZ archive. + Returns an ElementTree of the extracted KML. + """ + with zipfile.ZipFile(kmz_path, "r") as z: + # Find the first file ending with .kml (case‑insensitive) + kml_name = next((n for n in z.namelist() + if n.lower().endswith(".kml")), None) + if not kml_name: + raise ValueError(f"No KML file found inside {kmz_path}") + with z.open(kml_name) as kml_file: + return ET.parse(kml_file) + +def get_top_level_elements(kml_tree: ET.ElementTree) -> List[ET.Element]: + """ + Return a list of the top‑level elements that contain placemarks. + Common patterns are: + + + + """ + root = kml_tree.getroot() + # KML namespace handling (most KMLs use the same namespace) + ns = {"kml": "http://www.opengis.net/kml/2.2"} + # Find or or elements directly under root + elements = [] + for tag in ["Document", "Folder", "Placemark"]: + elements.extend(root.findall(f"kml:{tag}", ns)) + return elements + +def build_merged_kml(elements_by_file: List[List[ET.Element]]) -> ET.ElementTree: + """ + Build a new KML ElementTree that contains a single + wrapping all collected elements. + """ + kml_ns = "http://www.opengis.net/kml/2.2" + ET.register_namespace("", kml_ns) # ensure no prefix in output + + kml_root = ET.Element(f"{{{kml_ns}}}kml") + doc = ET.SubElement(kml_root, "Document") + + for elems in elements_by_file: + for elem in elems: + doc.append(elem) + + return ET.ElementTree(kml_root) + +# ------------------------------------------------------------ +# Main logic +# ------------------------------------------------------------ + +def main(input_folder: Path, output_file: Path): + kmz_files = find_kmz_files(input_folder) + if not kmz_files: + print(f"No .kmz files found in {input_folder}") + sys.exit(1) + + all_elements = [] + + for kmz in kmz_files: + try: + kml_tree = extract_kml_from_kmz(kmz) + elems = get_top_level_elements(kml_tree) + if not elems: + print(f"WARNING: No placemark elements found in {kmz}") + else: + all_elements.append(elems) + except Exception as e: + print(f"ERROR processing {kmz}: {e}") + + if not any(all_elements): + print("No placemark data to write.") + sys.exit(1) + + merged_tree = build_merged_kml(all_elements) + merged_tree.write(output_file, encoding="utf-8", xml_declaration=True) + print(f"Combined KML written to {output_file}") + +if __name__ == "__main__": + if len(sys.argv) != 3: + print("Usage: python combine_kmz_to_kml.py ") + sys.exit(1) + + input_dir = Path(sys.argv[1]).expanduser().resolve() + output_kml = Path(sys.argv[2]).expanduser().resolve() + + if not input_dir.is_dir(): + print(f"Input path {input_dir} is not a directory.") + sys.exit(1) + + main(input_dir, output_kml) \ No newline at end of file diff --git a/Code Snippets/rrig_kmz/linestring.txt b/Code Snippets/rrig_kmz/linestring.txt new file mode 100644 index 0000000..ca89715 --- /dev/null +++ b/Code Snippets/rrig_kmz/linestring.txt @@ -0,0 +1,3 @@ +LineString 1: +[[31.65053381256015, -103.1381372489133], [31.65078110147886, -103.1371939568141], [31.65137766837301, -103.135379572764], [31.65501734857683, -103.1216582043267], [31.66820232963991, -103.1267090001346], [31.66857428692562, -103.1254217441416], [31.68730649748832, -103.097869762411], [31.69401658057209, -103.0880082019376], [31.71262120882616, -103.0201699677156], [31.71246042343891, -103.0199628293717], [31.71229701578655, -103.0197573453124], [31.71245394748738, -103.0195184188874], [31.63091832800928, -102.9041726111906], [31.6165910414367, -102.8944523887092], [31.59718777074555, -102.8811494904473], [31.58231202839571, -102.8680137394599], [31.56931339800882, -102.8516886598823], [31.48448961907497, -102.7180735327187], [31.51503752317085, -102.7283930769256], [31.51898260340799, -102.7117114856601], [31.5330847136263, -102.7165257753119], [31.53686069788628, -102.7003948024066], [31.56540947523578, -102.7095293371793], [31.58496921843023, -102.6901307183483], [31.60301750051444, -102.6955769601148]] + diff --git a/Code Snippets/rrig_kmz/marker.txt b/Code Snippets/rrig_kmz/marker.txt new file mode 100644 index 0000000..a2b4377 --- /dev/null +++ b/Code Snippets/rrig_kmz/marker.txt @@ -0,0 +1,5 @@ +Node X: Cipher Interconnect: 31.69772151150734, -103.0755810899755 +Node D: 10" to 12" Transition - Wadell Valve: 31.48528462529936, -102.7191228273435 +Node F: US Silica: 31.60330030384848, -102.6955825380853 +RRIG Water Pump Station: 31.65239911273985, -103.1419105981684 +Node C: Monahans Booster Station: 31.59192479909473, -102.8767681214162 diff --git a/Code Snippets/rrig_kmz/out.kml b/Code Snippets/rrig_kmz/out.kml new file mode 100644 index 0000000..4361b98 --- /dev/null +++ b/Code Snippets/rrig_kmz/out.kml @@ -0,0 +1,352 @@ + + + Node X Cipher Interconnect.kmz + + + normal + #sn_X + + + highlight + #sh_X + + + + + + Node X: Cipher Interconnect + + -103.0664786491922 + 31.67995227525221 + 0 + -20.19425301511447 + 0.3113470562703879 + 19074.24725536319 + relativeToSeaFloor + + #msn_X + + 1 + -103.0755810899755,31.69772151150734,0 + + + + + + Node D 10 to 12 Transition - Wadell Valve.kmz + + + normal + #sn_D + + + highlight + #sh_D + + + + + + Node D: 10" to 12" Transition - Wadell Valve + This is a proposed booster station location. + +Before this proposed booster station is NEW 10" CS SCH/40 and after the pump it transitions to the existing 12" CS SCH/STD. + + -102.714901153744 + 31.49028973104173 + 0 + 0.2075710380470465 + 34.53924441923252 + 3707.334765680453 + relativeToSeaFloor + + #msn_D + + 1 + -102.7191228273435,31.48528462529936,0 + + + + + + Node F US Silica.kmz + + + normal + #sn_F + + + highlight + #sh_F + + + + + + Node F: US Silica + This is the final destination (US Silica). + + -102.7057483945038 + 31.58085164971466 + 0 + 0.1391520682125403 + 14.07815682751618 + 9472.365324672779 + relativeToSeaFloor + + #msn_F + 1 + + 1 + -102.6955825380853,31.60330030384848,0 + + + + + + RRIG Water Pump Station.kmz + + + normal + #sn_ylw-pushpin + + + highlight + #sh_ylw-pushpin + + + + + + RRIG Water Pump Station + + -103.1424336640816 + 31.65637246137589 + 0 + -0.01350029730544429 + 33.60918004711282 + 3855.687513264544 + relativeToSeaFloor + + #msn_ylw-pushpin + + 1 + -103.1419105981684,31.65239911273985,0 + + + + + + Node C Monahans Booster Station.kmz + + + normal + #sn_C + + + highlight + #sh_C + + + + + + Node C: Monahans Booster Station + Here is an exisiting booster station. The pumps here will require an upgrade/new pumps. +Before the booster station is 16" SDR-11 HDPE and after the pump it transitions to the existing worn 10" CS SCH/40. + + -102.8754448804377 + 31.59216413663673 + 0 + 0.02738240047835951 + 19.33959001588264 + 589.3935585480306 + relativeToSeaFloor + + #msn_C + + 1 + -102.8767681214162,31.59192479909473,0 + + + + + + Original - Rig PL wilth existing Azul PL.kmz + + + normal + #sn_ylw-pushpin96 + + + highlight + #sh_ylw-pushpin94 + + + + + + Original - Rig PL wilth existing Azul PL + #msn_ylw-pushpin89 + + 1 + + -103.1381372489133,31.65053381256015,0 -103.1371939568141,31.65078110147886,0 -103.135379572764,31.65137766837301,0 -103.1216582043267,31.65501734857683,0 -103.1267090001346,31.66820232963991,0 -103.1254217441416,31.66857428692562,0 -103.097869762411,31.68730649748832,0 -103.0880082019376,31.69401658057209,0 -103.0201699677156,31.71262120882616,0 -103.0199628293717,31.71246042343891,0 -103.0197573453124,31.71229701578655,0 -103.0195184188874,31.71245394748738,0 -102.9041726111906,31.63091832800928,0 -102.8944523887092,31.6165910414367,0 -102.8811494904473,31.59718777074555,0 -102.8680137394599,31.58231202839571,0 -102.8516886598823,31.56931339800882,0 -102.7180735327187,31.48448961907497,0 -102.7283930769256,31.51503752317085,0 -102.7117114856601,31.51898260340799,0 -102.7165257753119,31.5330847136263,0 -102.7003948024066,31.53686069788628,0 -102.7095293371793,31.56540947523578,0 -102.6901307183483,31.58496921843023,0 -102.6955769601148,31.60301750051444,0 + + + + + + \ No newline at end of file diff --git a/Code Snippets/rrig_kmz/polygon.txt b/Code Snippets/rrig_kmz/polygon.txt new file mode 100644 index 0000000..e69de29