From 0fa4cb99554008d229834423afa0550065e11028 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Fri, 22 Apr 2016 13:36:13 -0700 Subject: [PATCH] Import original source of Map-Splat 0.01 --- Changes | 5 + MANIFEST | 8 + Makefile.PL | 26 ++ Makefile.old | 856 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ README | 85 ++++++ Splat.pm | 521 ++++++++++++++++++++++++++++++++++++ ignore.txt | 18 ++ t/00-load.t | 13 + t/manifest.t | 15 ++ t/splat.t | 29 ++ 10 files changed, 1576 insertions(+) create mode 100644 Changes create mode 100644 MANIFEST create mode 100644 Makefile.PL create mode 100644 Makefile.old create mode 100644 README create mode 100644 Splat.pm create mode 100644 ignore.txt create mode 100644 t/00-load.t create mode 100644 t/manifest.t create mode 100644 t/splat.t diff --git a/Changes b/Changes new file mode 100644 index 0000000..e050fbc --- /dev/null +++ b/Changes @@ -0,0 +1,5 @@ +Revision history for Map-Splat + +0.01 Date/time + First version, released on an unsuspecting world. + diff --git a/MANIFEST b/MANIFEST new file mode 100644 index 0000000..8ec4231 --- /dev/null +++ b/MANIFEST @@ -0,0 +1,8 @@ +Changes +Splat.pm +Makefile.PL +MANIFEST This list of files +README +t/00-load.t +t/manifest.t +t/splat.t diff --git a/Makefile.PL b/Makefile.PL new file mode 100644 index 0000000..aee9697 --- /dev/null +++ b/Makefile.PL @@ -0,0 +1,26 @@ +use 5.006; +use strict; +use warnings FATAL => 'all'; +use ExtUtils::MakeMaker; + +WriteMakefile( + NAME => 'Map::Splat', + AUTHOR => q{Mark Wells }, + VERSION_FROM => 'Splat.pm', + ABSTRACT_FROM => 'Splat.pm', + LICENSE => 'Artistic_2_0', + PL_FILES => {}, + MIN_PERL_VERSION => 5.006, + CONFIGURE_REQUIRES => { + 'ExtUtils::MakeMaker' => 0, + }, + BUILD_REQUIRES => { + 'Test::More' => 0, + }, + PREREQ_PM => { + 'XML::LibXML' => 2, + 'Image::Magick' => 0, + }, + dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', }, + clean => { FILES => 'Map-Splat-*' }, +); diff --git a/Makefile.old b/Makefile.old new file mode 100644 index 0000000..d8927e7 --- /dev/null +++ b/Makefile.old @@ -0,0 +1,856 @@ +# This Makefile is for the Map::Splat extension to perl. +# +# It was generated automatically by MakeMaker version +# 7.0401 (Revision: 70401) from the contents of +# Makefile.PL. Don't edit this file, edit Makefile.PL instead. +# +# ANY CHANGES MADE HERE WILL BE LOST! +# +# MakeMaker ARGV: () +# + +# MakeMaker Parameters: + +# ABSTRACT_FROM => q[Splat.pm] +# AUTHOR => [q[Mark Wells ]] +# BUILD_REQUIRES => { Test::More=>q[0] } +# CONFIGURE_REQUIRES => { ExtUtils::MakeMaker=>q[0] } +# LICENSE => q[Artistic_2_0] +# MIN_PERL_VERSION => q[5.006] +# NAME => q[Map::Splat] +# PL_FILES => { } +# PREREQ_PM => { Test::More=>q[0] } +# TEST_REQUIRES => { } +# VERSION_FROM => q[Splat.pm] +# clean => { FILES=>q[Map-Splat-*] } +# dist => { COMPRESS=>q[gzip -9f], SUFFIX=>q[gz] } + +# --- MakeMaker post_initialize section: + + +# --- MakeMaker const_config section: + +# These definitions are from config.sh (via /usr/lib/x86_64-linux-gnu/perl/5.22/Config.pm). +# They may have been overridden via Makefile.PL or on the command line. +AR = ar +CC = x86_64-linux-gnu-gcc +CCCDLFLAGS = -fPIC +CCDLFLAGS = -Wl,-E +DLEXT = so +DLSRC = dl_dlopen.xs +EXE_EXT = +FULL_AR = /usr/bin/ar +LD = x86_64-linux-gnu-gcc +LDDLFLAGS = -shared -L/usr/local/lib -fstack-protector-strong +LDFLAGS = -fstack-protector-strong -L/usr/local/lib +LIBC = libc-2.21.so +LIB_EXT = .a +OBJ_EXT = .o +OSNAME = linux +OSVERS = 3.16.0 +RANLIB = : +SITELIBEXP = /usr/local/share/perl/5.22.1 +SITEARCHEXP = /usr/local/lib/x86_64-linux-gnu/perl/5.22.1 +SO = so +VENDORARCHEXP = /usr/lib/x86_64-linux-gnu/perl5/5.22 +VENDORLIBEXP = /usr/share/perl5 + + +# --- MakeMaker constants section: +AR_STATIC_ARGS = cr +DIRFILESEP = / +DFSEP = $(DIRFILESEP) +NAME = Map::Splat +NAME_SYM = Map_Splat +VERSION = 0.01 +VERSION_MACRO = VERSION +VERSION_SYM = 0_01 +DEFINE_VERSION = -D$(VERSION_MACRO)=\"$(VERSION)\" +XS_VERSION = 0.01 +XS_VERSION_MACRO = XS_VERSION +XS_DEFINE_VERSION = -D$(XS_VERSION_MACRO)=\"$(XS_VERSION)\" +INST_ARCHLIB = blib/arch +INST_SCRIPT = blib/script +INST_BIN = blib/bin +INST_LIB = blib/lib +INST_MAN1DIR = blib/man1 +INST_MAN3DIR = blib/man3 +MAN1EXT = 1p +MAN3EXT = 3pm +INSTALLDIRS = site +DESTDIR = +PREFIX = $(SITEPREFIX) +PERLPREFIX = /usr +SITEPREFIX = /usr/local +VENDORPREFIX = /usr +INSTALLPRIVLIB = /usr/share/perl/5.22 +DESTINSTALLPRIVLIB = $(DESTDIR)$(INSTALLPRIVLIB) +INSTALLSITELIB = /usr/local/share/perl/5.22.1 +DESTINSTALLSITELIB = $(DESTDIR)$(INSTALLSITELIB) +INSTALLVENDORLIB = /usr/share/perl5 +DESTINSTALLVENDORLIB = $(DESTDIR)$(INSTALLVENDORLIB) +INSTALLARCHLIB = /usr/lib/x86_64-linux-gnu/perl/5.22 +DESTINSTALLARCHLIB = $(DESTDIR)$(INSTALLARCHLIB) +INSTALLSITEARCH = /usr/local/lib/x86_64-linux-gnu/perl/5.22.1 +DESTINSTALLSITEARCH = $(DESTDIR)$(INSTALLSITEARCH) +INSTALLVENDORARCH = /usr/lib/x86_64-linux-gnu/perl5/5.22 +DESTINSTALLVENDORARCH = $(DESTDIR)$(INSTALLVENDORARCH) +INSTALLBIN = /usr/bin +DESTINSTALLBIN = $(DESTDIR)$(INSTALLBIN) +INSTALLSITEBIN = /usr/local/bin +DESTINSTALLSITEBIN = $(DESTDIR)$(INSTALLSITEBIN) +INSTALLVENDORBIN = /usr/bin +DESTINSTALLVENDORBIN = $(DESTDIR)$(INSTALLVENDORBIN) +INSTALLSCRIPT = /usr/bin +DESTINSTALLSCRIPT = $(DESTDIR)$(INSTALLSCRIPT) +INSTALLSITESCRIPT = /usr/local/bin +DESTINSTALLSITESCRIPT = $(DESTDIR)$(INSTALLSITESCRIPT) +INSTALLVENDORSCRIPT = /usr/bin +DESTINSTALLVENDORSCRIPT = $(DESTDIR)$(INSTALLVENDORSCRIPT) +INSTALLMAN1DIR = /usr/share/man/man1 +DESTINSTALLMAN1DIR = $(DESTDIR)$(INSTALLMAN1DIR) +INSTALLSITEMAN1DIR = /usr/local/man/man1 +DESTINSTALLSITEMAN1DIR = $(DESTDIR)$(INSTALLSITEMAN1DIR) +INSTALLVENDORMAN1DIR = /usr/share/man/man1 +DESTINSTALLVENDORMAN1DIR = $(DESTDIR)$(INSTALLVENDORMAN1DIR) +INSTALLMAN3DIR = /usr/share/man/man3 +DESTINSTALLMAN3DIR = $(DESTDIR)$(INSTALLMAN3DIR) +INSTALLSITEMAN3DIR = /usr/local/man/man3 +DESTINSTALLSITEMAN3DIR = $(DESTDIR)$(INSTALLSITEMAN3DIR) +INSTALLVENDORMAN3DIR = /usr/share/man/man3 +DESTINSTALLVENDORMAN3DIR = $(DESTDIR)$(INSTALLVENDORMAN3DIR) +PERL_LIB = /usr/share/perl/5.22 +PERL_ARCHLIB = /usr/lib/x86_64-linux-gnu/perl/5.22 +PERL_ARCHLIBDEP = /usr/lib/x86_64-linux-gnu/perl/5.22 +LIBPERL_A = libperl.a +FIRST_MAKEFILE = Makefile +MAKEFILE_OLD = Makefile.old +MAKE_APERL_FILE = Makefile.aperl +PERLMAINCC = $(CC) +PERL_INC = /usr/lib/x86_64-linux-gnu/perl/5.22/CORE +PERL_INCDEP = /usr/lib/x86_64-linux-gnu/perl/5.22/CORE +PERL = "/usr/bin/perl" +FULLPERL = "/usr/bin/perl" +ABSPERL = $(PERL) +PERLRUN = $(PERL) +FULLPERLRUN = $(FULLPERL) +ABSPERLRUN = $(ABSPERL) +PERLRUNINST = $(PERLRUN) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" +FULLPERLRUNINST = $(FULLPERLRUN) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" +ABSPERLRUNINST = $(ABSPERLRUN) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" +PERL_CORE = 0 +PERM_DIR = 755 +PERM_RW = 644 +PERM_RWX = 755 + +MAKEMAKER = /usr/share/perl/5.22/ExtUtils/MakeMaker.pm +MM_VERSION = 7.0401 +MM_REVISION = 70401 + +# FULLEXT = Pathname for extension directory (eg Foo/Bar/Oracle). +# BASEEXT = Basename part of FULLEXT. May be just equal FULLEXT. (eg Oracle) +# PARENT_NAME = NAME without BASEEXT and no trailing :: (eg Foo::Bar) +# DLBASE = Basename part of dynamic library. May be just equal BASEEXT. +MAKE = make +FULLEXT = Map/Splat +BASEEXT = Splat +PARENT_NAME = Map +DLBASE = $(BASEEXT) +VERSION_FROM = Splat.pm +OBJECT = +LDFROM = $(OBJECT) +LINKTYPE = dynamic +BOOTDEP = + +# Handy lists of source code files: +XS_FILES = +C_FILES = +O_FILES = +H_FILES = +MAN1PODS = +MAN3PODS = Splat.pm + +# Where is the Config information that we are using/depend on +CONFIGDEP = $(PERL_ARCHLIBDEP)$(DFSEP)Config.pm $(PERL_INCDEP)$(DFSEP)config.h + +# Where to build things +INST_LIBDIR = $(INST_LIB)/Map +INST_ARCHLIBDIR = $(INST_ARCHLIB)/Map + +INST_AUTODIR = $(INST_LIB)/auto/$(FULLEXT) +INST_ARCHAUTODIR = $(INST_ARCHLIB)/auto/$(FULLEXT) + +INST_STATIC = +INST_DYNAMIC = +INST_BOOT = + +# Extra linker info +EXPORT_LIST = +PERL_ARCHIVE = +PERL_ARCHIVEDEP = +PERL_ARCHIVE_AFTER = + + +TO_INST_PM = Splat.pm + +PM_TO_BLIB = Splat.pm \ + $(INST_LIB)/Map/Splat.pm + + +# --- MakeMaker platform_constants section: +MM_Unix_VERSION = 7.0401 +PERL_MALLOC_DEF = -DPERL_EXTMALLOC_DEF -Dmalloc=Perl_malloc -Dfree=Perl_mfree -Drealloc=Perl_realloc -Dcalloc=Perl_calloc + + +# --- MakeMaker tool_autosplit section: +# Usage: $(AUTOSPLITFILE) FileToSplit AutoDirToSplitInto +AUTOSPLITFILE = $(ABSPERLRUN) -e 'use AutoSplit; autosplit($$$$ARGV[0], $$$$ARGV[1], 0, 1, 1)' -- + + + +# --- MakeMaker tool_xsubpp section: + + +# --- MakeMaker tools_other section: +SHELL = /bin/sh +CHMOD = chmod +CP = cp +MV = mv +NOOP = $(TRUE) +NOECHO = @ +RM_F = rm -f +RM_RF = rm -rf +TEST_F = test -f +TOUCH = touch +UMASK_NULL = umask 0 +DEV_NULL = > /dev/null 2>&1 +MKPATH = $(ABSPERLRUN) -MExtUtils::Command -e 'mkpath' -- +EQUALIZE_TIMESTAMP = $(ABSPERLRUN) -MExtUtils::Command -e 'eqtime' -- +FALSE = false +TRUE = true +ECHO = echo +ECHO_N = echo -n +UNINST = 0 +VERBINST = 0 +MOD_INSTALL = $(ABSPERLRUN) -MExtUtils::Install -e 'install([ from_to => {@ARGV}, verbose => '\''$(VERBINST)'\'', uninstall_shadows => '\''$(UNINST)'\'', dir_mode => '\''$(PERM_DIR)'\'' ]);' -- +DOC_INSTALL = $(ABSPERLRUN) -MExtUtils::Command::MM -e 'perllocal_install' -- +UNINSTALL = $(ABSPERLRUN) -MExtUtils::Command::MM -e 'uninstall' -- +WARN_IF_OLD_PACKLIST = $(ABSPERLRUN) -MExtUtils::Command::MM -e 'warn_if_old_packlist' -- +MACROSTART = +MACROEND = +USEMAKEFILE = -f +FIXIN = $(ABSPERLRUN) -MExtUtils::MY -e 'MY->fixin(shift)' -- +CP_NONEMPTY = $(ABSPERLRUN) -MExtUtils::Command::MM -e 'cp_nonempty' -- + + +# --- MakeMaker makemakerdflt section: +makemakerdflt : all + $(NOECHO) $(NOOP) + + +# --- MakeMaker dist section: +TAR = tar +TARFLAGS = cvf +ZIP = zip +ZIPFLAGS = -r +COMPRESS = gzip -9f +SUFFIX = .gz +SHAR = shar +PREOP = $(NOECHO) $(NOOP) +POSTOP = $(NOECHO) $(NOOP) +TO_UNIX = $(NOECHO) $(NOOP) +CI = ci -u +RCS_LABEL = rcs -Nv$(VERSION_SYM): -q +DIST_CP = best +DIST_DEFAULT = tardist +DISTNAME = Map-Splat +DISTVNAME = Map-Splat-0.01 + + +# --- MakeMaker macro section: + + +# --- MakeMaker depend section: + + +# --- MakeMaker cflags section: + + +# --- MakeMaker const_loadlibs section: + + +# --- MakeMaker const_cccmd section: + + +# --- MakeMaker post_constants section: + + +# --- MakeMaker pasthru section: + +PASTHRU = LIBPERL_A="$(LIBPERL_A)"\ + LINKTYPE="$(LINKTYPE)"\ + LD="$(LD)"\ + PREFIX="$(PREFIX)" + + +# --- MakeMaker special_targets section: +.SUFFIXES : .xs .c .C .cpp .i .s .cxx .cc $(OBJ_EXT) + +.PHONY: all config static dynamic test linkext manifest blibdirs clean realclean disttest distdir + + + +# --- MakeMaker c_o section: + + +# --- MakeMaker xs_c section: + + +# --- MakeMaker xs_o section: + + +# --- MakeMaker top_targets section: +all :: pure_all manifypods + $(NOECHO) $(NOOP) + + +pure_all :: config pm_to_blib subdirs linkext + $(NOECHO) $(NOOP) + +subdirs :: $(MYEXTLIB) + $(NOECHO) $(NOOP) + +config :: $(FIRST_MAKEFILE) blibdirs + $(NOECHO) $(NOOP) + +help : + perldoc ExtUtils::MakeMaker + + +# --- MakeMaker blibdirs section: +blibdirs : $(INST_LIBDIR)$(DFSEP).exists $(INST_ARCHLIB)$(DFSEP).exists $(INST_AUTODIR)$(DFSEP).exists $(INST_ARCHAUTODIR)$(DFSEP).exists $(INST_BIN)$(DFSEP).exists $(INST_SCRIPT)$(DFSEP).exists $(INST_MAN1DIR)$(DFSEP).exists $(INST_MAN3DIR)$(DFSEP).exists + $(NOECHO) $(NOOP) + +# Backwards compat with 6.18 through 6.25 +blibdirs.ts : blibdirs + $(NOECHO) $(NOOP) + +$(INST_LIBDIR)$(DFSEP).exists :: Makefile.PL + $(NOECHO) $(MKPATH) $(INST_LIBDIR) + $(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_LIBDIR) + $(NOECHO) $(TOUCH) $(INST_LIBDIR)$(DFSEP).exists + +$(INST_ARCHLIB)$(DFSEP).exists :: Makefile.PL + $(NOECHO) $(MKPATH) $(INST_ARCHLIB) + $(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_ARCHLIB) + $(NOECHO) $(TOUCH) $(INST_ARCHLIB)$(DFSEP).exists + +$(INST_AUTODIR)$(DFSEP).exists :: Makefile.PL + $(NOECHO) $(MKPATH) $(INST_AUTODIR) + $(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_AUTODIR) + $(NOECHO) $(TOUCH) $(INST_AUTODIR)$(DFSEP).exists + +$(INST_ARCHAUTODIR)$(DFSEP).exists :: Makefile.PL + $(NOECHO) $(MKPATH) $(INST_ARCHAUTODIR) + $(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_ARCHAUTODIR) + $(NOECHO) $(TOUCH) $(INST_ARCHAUTODIR)$(DFSEP).exists + +$(INST_BIN)$(DFSEP).exists :: Makefile.PL + $(NOECHO) $(MKPATH) $(INST_BIN) + $(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_BIN) + $(NOECHO) $(TOUCH) $(INST_BIN)$(DFSEP).exists + +$(INST_SCRIPT)$(DFSEP).exists :: Makefile.PL + $(NOECHO) $(MKPATH) $(INST_SCRIPT) + $(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_SCRIPT) + $(NOECHO) $(TOUCH) $(INST_SCRIPT)$(DFSEP).exists + +$(INST_MAN1DIR)$(DFSEP).exists :: Makefile.PL + $(NOECHO) $(MKPATH) $(INST_MAN1DIR) + $(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_MAN1DIR) + $(NOECHO) $(TOUCH) $(INST_MAN1DIR)$(DFSEP).exists + +$(INST_MAN3DIR)$(DFSEP).exists :: Makefile.PL + $(NOECHO) $(MKPATH) $(INST_MAN3DIR) + $(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_MAN3DIR) + $(NOECHO) $(TOUCH) $(INST_MAN3DIR)$(DFSEP).exists + + + +# --- MakeMaker linkext section: + +linkext :: $(LINKTYPE) + $(NOECHO) $(NOOP) + + +# --- MakeMaker dlsyms section: + + +# --- MakeMaker dynamic_bs section: + +BOOTSTRAP = + + +# --- MakeMaker dynamic section: + +dynamic :: $(FIRST_MAKEFILE) $(BOOTSTRAP) $(INST_DYNAMIC) + $(NOECHO) $(NOOP) + + +# --- MakeMaker dynamic_lib section: + + +# --- MakeMaker static section: + +## $(INST_PM) has been moved to the all: target. +## It remains here for awhile to allow for old usage: "make static" +static :: $(FIRST_MAKEFILE) $(INST_STATIC) + $(NOECHO) $(NOOP) + + +# --- MakeMaker static_lib section: + + +# --- MakeMaker manifypods section: + +POD2MAN_EXE = $(PERLRUN) "-MExtUtils::Command::MM" -e pod2man "--" +POD2MAN = $(POD2MAN_EXE) + + +manifypods : pure_all \ + Splat.pm + $(NOECHO) $(POD2MAN) --section=$(MAN3EXT) --perm_rw=$(PERM_RW) -u \ + Splat.pm $(INST_MAN3DIR)/Map::Splat.$(MAN3EXT) + + + + +# --- MakeMaker processPL section: + + +# --- MakeMaker installbin section: + + +# --- MakeMaker subdirs section: + +# none + +# --- MakeMaker clean_subdirs section: +clean_subdirs : + $(NOECHO) $(NOOP) + + +# --- MakeMaker clean section: + +# Delete temporary files but do not touch installed files. We don't delete +# the Makefile here so a later make realclean still has a makefile to use. + +clean :: clean_subdirs + - $(RM_F) \ + $(BASEEXT).bso $(BASEEXT).def \ + $(BASEEXT).exp $(BASEEXT).x \ + $(BOOTSTRAP) $(INST_ARCHAUTODIR)/extralibs.all \ + $(INST_ARCHAUTODIR)/extralibs.ld $(MAKE_APERL_FILE) \ + *$(LIB_EXT) *$(OBJ_EXT) \ + *perl.core MYMETA.json \ + MYMETA.yml blibdirs.ts \ + core core.*perl.*.? \ + core.[0-9] core.[0-9][0-9] \ + core.[0-9][0-9][0-9] core.[0-9][0-9][0-9][0-9] \ + core.[0-9][0-9][0-9][0-9][0-9] lib$(BASEEXT).def \ + mon.out perl \ + perl$(EXE_EXT) perl.exe \ + perlmain.c pm_to_blib \ + pm_to_blib.ts so_locations \ + tmon.out + - $(RM_RF) \ + Map-Splat-* blib + $(NOECHO) $(RM_F) $(MAKEFILE_OLD) + - $(MV) $(FIRST_MAKEFILE) $(MAKEFILE_OLD) $(DEV_NULL) + + +# --- MakeMaker realclean_subdirs section: +realclean_subdirs : + $(NOECHO) $(NOOP) + + +# --- MakeMaker realclean section: +# Delete temporary files (via clean) and also delete dist files +realclean purge :: clean realclean_subdirs + - $(RM_F) \ + $(FIRST_MAKEFILE) $(MAKEFILE_OLD) + - $(RM_RF) \ + $(DISTVNAME) + + +# --- MakeMaker metafile section: +metafile : create_distdir + $(NOECHO) $(ECHO) Generating META.yml + $(NOECHO) $(ECHO) '---' > META_new.yml + $(NOECHO) $(ECHO) 'abstract: '\''Wrapper for the Splat! RF propagation modeling tool'\''' >> META_new.yml + $(NOECHO) $(ECHO) 'author:' >> META_new.yml + $(NOECHO) $(ECHO) ' - '\''Mark Wells '\''' >> META_new.yml + $(NOECHO) $(ECHO) 'build_requires:' >> META_new.yml + $(NOECHO) $(ECHO) ' Test::More: '\''0'\''' >> META_new.yml + $(NOECHO) $(ECHO) 'configure_requires:' >> META_new.yml + $(NOECHO) $(ECHO) ' ExtUtils::MakeMaker: '\''0'\''' >> META_new.yml + $(NOECHO) $(ECHO) 'dynamic_config: 1' >> META_new.yml + $(NOECHO) $(ECHO) 'generated_by: '\''ExtUtils::MakeMaker version 7.0401, CPAN::Meta::Converter version 2.150005'\''' >> META_new.yml + $(NOECHO) $(ECHO) 'license: unknown' >> META_new.yml + $(NOECHO) $(ECHO) 'meta-spec:' >> META_new.yml + $(NOECHO) $(ECHO) ' url: http://module-build.sourceforge.net/META-spec-v1.4.html' >> META_new.yml + $(NOECHO) $(ECHO) ' version: '\''1.4'\''' >> META_new.yml + $(NOECHO) $(ECHO) 'name: Map-Splat' >> META_new.yml + $(NOECHO) $(ECHO) 'no_index:' >> META_new.yml + $(NOECHO) $(ECHO) ' directory:' >> META_new.yml + $(NOECHO) $(ECHO) ' - t' >> META_new.yml + $(NOECHO) $(ECHO) ' - inc' >> META_new.yml + $(NOECHO) $(ECHO) 'requires:' >> META_new.yml + $(NOECHO) $(ECHO) ' perl: '\''5.006'\''' >> META_new.yml + $(NOECHO) $(ECHO) 'version: '\''0.01'\''' >> META_new.yml + $(NOECHO) $(ECHO) 'x_serialization_backend: '\''CPAN::Meta::YAML version 0.012'\''' >> META_new.yml + -$(NOECHO) $(MV) META_new.yml $(DISTVNAME)/META.yml + $(NOECHO) $(ECHO) Generating META.json + $(NOECHO) $(ECHO) '{' > META_new.json + $(NOECHO) $(ECHO) ' "abstract" : "Wrapper for the Splat! RF propagation modeling tool",' >> META_new.json + $(NOECHO) $(ECHO) ' "author" : [' >> META_new.json + $(NOECHO) $(ECHO) ' "Mark Wells "' >> META_new.json + $(NOECHO) $(ECHO) ' ],' >> META_new.json + $(NOECHO) $(ECHO) ' "dynamic_config" : 1,' >> META_new.json + $(NOECHO) $(ECHO) ' "generated_by" : "ExtUtils::MakeMaker version 7.0401, CPAN::Meta::Converter version 2.150005",' >> META_new.json + $(NOECHO) $(ECHO) ' "license" : [' >> META_new.json + $(NOECHO) $(ECHO) ' "unknown"' >> META_new.json + $(NOECHO) $(ECHO) ' ],' >> META_new.json + $(NOECHO) $(ECHO) ' "meta-spec" : {' >> META_new.json + $(NOECHO) $(ECHO) ' "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",' >> META_new.json + $(NOECHO) $(ECHO) ' "version" : "2"' >> META_new.json + $(NOECHO) $(ECHO) ' },' >> META_new.json + $(NOECHO) $(ECHO) ' "name" : "Map-Splat",' >> META_new.json + $(NOECHO) $(ECHO) ' "no_index" : {' >> META_new.json + $(NOECHO) $(ECHO) ' "directory" : [' >> META_new.json + $(NOECHO) $(ECHO) ' "t",' >> META_new.json + $(NOECHO) $(ECHO) ' "inc"' >> META_new.json + $(NOECHO) $(ECHO) ' ]' >> META_new.json + $(NOECHO) $(ECHO) ' },' >> META_new.json + $(NOECHO) $(ECHO) ' "prereqs" : {' >> META_new.json + $(NOECHO) $(ECHO) ' "build" : {' >> META_new.json + $(NOECHO) $(ECHO) ' "requires" : {' >> META_new.json + $(NOECHO) $(ECHO) ' "Test::More" : "0"' >> META_new.json + $(NOECHO) $(ECHO) ' }' >> META_new.json + $(NOECHO) $(ECHO) ' },' >> META_new.json + $(NOECHO) $(ECHO) ' "configure" : {' >> META_new.json + $(NOECHO) $(ECHO) ' "requires" : {' >> META_new.json + $(NOECHO) $(ECHO) ' "ExtUtils::MakeMaker" : "0"' >> META_new.json + $(NOECHO) $(ECHO) ' }' >> META_new.json + $(NOECHO) $(ECHO) ' },' >> META_new.json + $(NOECHO) $(ECHO) ' "runtime" : {' >> META_new.json + $(NOECHO) $(ECHO) ' "requires" : {' >> META_new.json + $(NOECHO) $(ECHO) ' "perl" : "5.006"' >> META_new.json + $(NOECHO) $(ECHO) ' }' >> META_new.json + $(NOECHO) $(ECHO) ' }' >> META_new.json + $(NOECHO) $(ECHO) ' },' >> META_new.json + $(NOECHO) $(ECHO) ' "release_status" : "stable",' >> META_new.json + $(NOECHO) $(ECHO) ' "version" : "0.01",' >> META_new.json + $(NOECHO) $(ECHO) ' "x_serialization_backend" : "JSON::PP version 2.27300"' >> META_new.json + $(NOECHO) $(ECHO) '}' >> META_new.json + -$(NOECHO) $(MV) META_new.json $(DISTVNAME)/META.json + + +# --- MakeMaker signature section: +signature : + cpansign -s + + +# --- MakeMaker dist_basics section: +distclean :: realclean distcheck + $(NOECHO) $(NOOP) + +distcheck : + $(PERLRUN) "-MExtUtils::Manifest=fullcheck" -e fullcheck + +skipcheck : + $(PERLRUN) "-MExtUtils::Manifest=skipcheck" -e skipcheck + +manifest : + $(PERLRUN) "-MExtUtils::Manifest=mkmanifest" -e mkmanifest + +veryclean : realclean + $(RM_F) *~ */*~ *.orig */*.orig *.bak */*.bak *.old */*.old + + + +# --- MakeMaker dist_core section: + +dist : $(DIST_DEFAULT) $(FIRST_MAKEFILE) + $(NOECHO) $(ABSPERLRUN) -l -e 'print '\''Warning: Makefile possibly out of date with $(VERSION_FROM)'\''' \ + -e ' if -e '\''$(VERSION_FROM)'\'' and -M '\''$(VERSION_FROM)'\'' < -M '\''$(FIRST_MAKEFILE)'\'';' -- + +tardist : $(DISTVNAME).tar$(SUFFIX) + $(NOECHO) $(NOOP) + +uutardist : $(DISTVNAME).tar$(SUFFIX) + uuencode $(DISTVNAME).tar$(SUFFIX) $(DISTVNAME).tar$(SUFFIX) > $(DISTVNAME).tar$(SUFFIX)_uu + $(NOECHO) $(ECHO) 'Created $(DISTVNAME).tar$(SUFFIX)_uu' + +$(DISTVNAME).tar$(SUFFIX) : distdir + $(PREOP) + $(TO_UNIX) + $(TAR) $(TARFLAGS) $(DISTVNAME).tar $(DISTVNAME) + $(RM_RF) $(DISTVNAME) + $(COMPRESS) $(DISTVNAME).tar + $(NOECHO) $(ECHO) 'Created $(DISTVNAME).tar$(SUFFIX)' + $(POSTOP) + +zipdist : $(DISTVNAME).zip + $(NOECHO) $(NOOP) + +$(DISTVNAME).zip : distdir + $(PREOP) + $(ZIP) $(ZIPFLAGS) $(DISTVNAME).zip $(DISTVNAME) + $(RM_RF) $(DISTVNAME) + $(NOECHO) $(ECHO) 'Created $(DISTVNAME).zip' + $(POSTOP) + +shdist : distdir + $(PREOP) + $(SHAR) $(DISTVNAME) > $(DISTVNAME).shar + $(RM_RF) $(DISTVNAME) + $(NOECHO) $(ECHO) 'Created $(DISTVNAME).shar' + $(POSTOP) + + +# --- MakeMaker distdir section: +create_distdir : + $(RM_RF) $(DISTVNAME) + $(PERLRUN) "-MExtUtils::Manifest=manicopy,maniread" \ + -e "manicopy(maniread(),'$(DISTVNAME)', '$(DIST_CP)');" + +distdir : create_distdir distmeta + $(NOECHO) $(NOOP) + + + +# --- MakeMaker dist_test section: +disttest : distdir + cd $(DISTVNAME) && $(ABSPERLRUN) Makefile.PL + cd $(DISTVNAME) && $(MAKE) $(PASTHRU) + cd $(DISTVNAME) && $(MAKE) test $(PASTHRU) + + + +# --- MakeMaker dist_ci section: + +ci : + $(PERLRUN) "-MExtUtils::Manifest=maniread" \ + -e "@all = keys %{ maniread() };" \ + -e "print(qq{Executing $(CI) @all\n}); system(qq{$(CI) @all});" \ + -e "print(qq{Executing $(RCS_LABEL) ...\n}); system(qq{$(RCS_LABEL) @all});" + + +# --- MakeMaker distmeta section: +distmeta : create_distdir metafile + $(NOECHO) cd $(DISTVNAME) && $(ABSPERLRUN) -MExtUtils::Manifest=maniadd -e 'exit unless -e q{META.yml};' \ + -e 'eval { maniadd({q{META.yml} => q{Module YAML meta-data (added by MakeMaker)}}) }' \ + -e ' or print "Could not add META.yml to MANIFEST: $$$${'\''@'\''}\n"' -- + $(NOECHO) cd $(DISTVNAME) && $(ABSPERLRUN) -MExtUtils::Manifest=maniadd -e 'exit unless -f q{META.json};' \ + -e 'eval { maniadd({q{META.json} => q{Module JSON meta-data (added by MakeMaker)}}) }' \ + -e ' or print "Could not add META.json to MANIFEST: $$$${'\''@'\''}\n"' -- + + + +# --- MakeMaker distsignature section: +distsignature : create_distdir + $(NOECHO) cd $(DISTVNAME) && $(ABSPERLRUN) -MExtUtils::Manifest=maniadd -e 'eval { maniadd({q{SIGNATURE} => q{Public-key signature (added by MakeMaker)}}) }' \ + -e ' or print "Could not add SIGNATURE to MANIFEST: $$$${'\''@'\''}\n"' -- + $(NOECHO) cd $(DISTVNAME) && $(TOUCH) SIGNATURE + cd $(DISTVNAME) && cpansign -s + + + +# --- MakeMaker install section: + +install :: pure_install doc_install + $(NOECHO) $(NOOP) + +install_perl :: pure_perl_install doc_perl_install + $(NOECHO) $(NOOP) + +install_site :: pure_site_install doc_site_install + $(NOECHO) $(NOOP) + +install_vendor :: pure_vendor_install doc_vendor_install + $(NOECHO) $(NOOP) + +pure_install :: pure_$(INSTALLDIRS)_install + $(NOECHO) $(NOOP) + +doc_install :: doc_$(INSTALLDIRS)_install + $(NOECHO) $(NOOP) + +pure__install : pure_site_install + $(NOECHO) $(ECHO) INSTALLDIRS not defined, defaulting to INSTALLDIRS=site + +doc__install : doc_site_install + $(NOECHO) $(ECHO) INSTALLDIRS not defined, defaulting to INSTALLDIRS=site + +pure_perl_install :: all + $(NOECHO) umask 022; $(MOD_INSTALL) \ + "$(INST_LIB)" "$(DESTINSTALLPRIVLIB)" \ + "$(INST_ARCHLIB)" "$(DESTINSTALLARCHLIB)" \ + "$(INST_BIN)" "$(DESTINSTALLBIN)" \ + "$(INST_SCRIPT)" "$(DESTINSTALLSCRIPT)" \ + "$(INST_MAN1DIR)" "$(DESTINSTALLMAN1DIR)" \ + "$(INST_MAN3DIR)" "$(DESTINSTALLMAN3DIR)" + $(NOECHO) $(WARN_IF_OLD_PACKLIST) \ + "$(SITEARCHEXP)/auto/$(FULLEXT)" + + +pure_site_install :: all + $(NOECHO) umask 02; $(MOD_INSTALL) \ + read "$(SITEARCHEXP)/auto/$(FULLEXT)/.packlist" \ + write "$(DESTINSTALLSITEARCH)/auto/$(FULLEXT)/.packlist" \ + "$(INST_LIB)" "$(DESTINSTALLSITELIB)" \ + "$(INST_ARCHLIB)" "$(DESTINSTALLSITEARCH)" \ + "$(INST_BIN)" "$(DESTINSTALLSITEBIN)" \ + "$(INST_SCRIPT)" "$(DESTINSTALLSITESCRIPT)" \ + "$(INST_MAN1DIR)" "$(DESTINSTALLSITEMAN1DIR)" \ + "$(INST_MAN3DIR)" "$(DESTINSTALLSITEMAN3DIR)" + $(NOECHO) $(WARN_IF_OLD_PACKLIST) \ + "$(PERL_ARCHLIB)/auto/$(FULLEXT)" + +pure_vendor_install :: all + $(NOECHO) umask 022; $(MOD_INSTALL) \ + "$(INST_LIB)" "$(DESTINSTALLVENDORLIB)" \ + "$(INST_ARCHLIB)" "$(DESTINSTALLVENDORARCH)" \ + "$(INST_BIN)" "$(DESTINSTALLVENDORBIN)" \ + "$(INST_SCRIPT)" "$(DESTINSTALLVENDORSCRIPT)" \ + "$(INST_MAN1DIR)" "$(DESTINSTALLVENDORMAN1DIR)" \ + "$(INST_MAN3DIR)" "$(DESTINSTALLVENDORMAN3DIR)" + + +doc_perl_install :: all + +doc_site_install :: all + $(NOECHO) $(ECHO) Appending installation info to "$(DESTINSTALLSITEARCH)/perllocal.pod" + -$(NOECHO) umask 02; $(MKPATH) "$(DESTINSTALLSITEARCH)" + -$(NOECHO) umask 02; $(DOC_INSTALL) \ + "Module" "$(NAME)" \ + "installed into" $(INSTALLSITELIB) \ + LINKTYPE "$(LINKTYPE)" \ + VERSION "$(VERSION)" \ + EXE_FILES "$(EXE_FILES)" \ + >> "$(DESTINSTALLSITEARCH)/perllocal.pod" + +doc_vendor_install :: all + + +uninstall :: uninstall_from_$(INSTALLDIRS)dirs + $(NOECHO) $(NOOP) + +uninstall_from_perldirs :: + +uninstall_from_sitedirs :: + $(NOECHO) $(UNINSTALL) "$(SITEARCHEXP)/auto/$(FULLEXT)/.packlist" + +uninstall_from_vendordirs :: + + +# --- MakeMaker force section: +# Phony target to force checking subdirectories. +FORCE : + $(NOECHO) $(NOOP) + + +# --- MakeMaker perldepend section: + + +# --- MakeMaker makefile section: +# We take a very conservative approach here, but it's worth it. +# We move Makefile to Makefile.old here to avoid gnu make looping. +$(FIRST_MAKEFILE) : Makefile.PL $(CONFIGDEP) + $(NOECHO) $(ECHO) "Makefile out-of-date with respect to $?" + $(NOECHO) $(ECHO) "Cleaning current config before rebuilding Makefile..." + -$(NOECHO) $(RM_F) $(MAKEFILE_OLD) + -$(NOECHO) $(MV) $(FIRST_MAKEFILE) $(MAKEFILE_OLD) + - $(MAKE) $(USEMAKEFILE) $(MAKEFILE_OLD) clean $(DEV_NULL) + $(PERLRUN) Makefile.PL + $(NOECHO) $(ECHO) "==> Your Makefile has been rebuilt. <==" + $(NOECHO) $(ECHO) "==> Please rerun the $(MAKE) command. <==" + $(FALSE) + + + +# --- MakeMaker staticmake section: + +# --- MakeMaker makeaperl section --- +MAP_TARGET = perl +FULLPERL = "/usr/bin/perl" + +$(MAP_TARGET) :: static $(MAKE_APERL_FILE) + $(MAKE) $(USEMAKEFILE) $(MAKE_APERL_FILE) $@ + +$(MAKE_APERL_FILE) : $(FIRST_MAKEFILE) pm_to_blib + $(NOECHO) $(ECHO) Writing \"$(MAKE_APERL_FILE)\" for this $(MAP_TARGET) + $(NOECHO) $(PERLRUNINST) \ + Makefile.PL DIR="" \ + MAKEFILE=$(MAKE_APERL_FILE) LINKTYPE=static \ + MAKEAPERL=1 NORECURS=1 CCCDLFLAGS= + + +# --- MakeMaker test section: + +TEST_VERBOSE=0 +TEST_TYPE=test_$(LINKTYPE) +TEST_FILE = test.pl +TEST_FILES = t/*.t +TESTDB_SW = -d + +testdb :: testdb_$(LINKTYPE) + +test :: $(TEST_TYPE) subdirs-test + +subdirs-test :: + $(NOECHO) $(NOOP) + + +test_dynamic :: pure_all + PERL_DL_NONLAZY=1 $(FULLPERLRUN) "-MExtUtils::Command::MM" "-MTest::Harness" "-e" "undef *Test::Harness::Switches; test_harness($(TEST_VERBOSE), '$(INST_LIB)', '$(INST_ARCHLIB)')" $(TEST_FILES) + +testdb_dynamic :: pure_all + PERL_DL_NONLAZY=1 $(FULLPERLRUN) $(TESTDB_SW) "-I$(INST_LIB)" "-I$(INST_ARCHLIB)" $(TEST_FILE) + +test_ : test_dynamic + +test_static :: test_dynamic +testdb_static :: testdb_dynamic + + +# --- MakeMaker ppd section: +# Creates a PPD (Perl Package Description) for a binary distribution. +ppd : + $(NOECHO) $(ECHO) '' > $(DISTNAME).ppd + $(NOECHO) $(ECHO) ' Wrapper for the Splat! RF propagation modeling tool' >> $(DISTNAME).ppd + $(NOECHO) $(ECHO) ' Mark Wells <mark@freeside.biz>' >> $(DISTNAME).ppd + $(NOECHO) $(ECHO) ' ' >> $(DISTNAME).ppd + $(NOECHO) $(ECHO) ' ' >> $(DISTNAME).ppd + $(NOECHO) $(ECHO) ' ' >> $(DISTNAME).ppd + $(NOECHO) $(ECHO) ' ' >> $(DISTNAME).ppd + $(NOECHO) $(ECHO) ' ' >> $(DISTNAME).ppd + $(NOECHO) $(ECHO) '' >> $(DISTNAME).ppd + + +# --- MakeMaker pm_to_blib section: + +pm_to_blib : $(FIRST_MAKEFILE) $(TO_INST_PM) + $(NOECHO) $(ABSPERLRUN) -MExtUtils::Install -e 'pm_to_blib({@ARGV}, '\''$(INST_LIB)/auto'\'', q[$(PM_FILTER)], '\''$(PERM_DIR)'\'')' -- \ + Splat.pm $(INST_LIB)/Map/Splat.pm + $(NOECHO) $(TOUCH) pm_to_blib + + +# --- MakeMaker selfdocument section: + + +# --- MakeMaker postamble section: + + +# End. diff --git a/README b/README new file mode 100644 index 0000000..95ba4ba --- /dev/null +++ b/README @@ -0,0 +1,85 @@ +Map-Splat + +The README is used to introduce the module and provide instructions on +how to install the module, any machine dependencies it may have (for +example C compilers and installed libraries) and any other information +that should be provided before the module is installed. + +A README file is required for CPAN modules since CPAN extracts the README +file from a module distribution so that people browsing the archive +can use it to get an idea of the module's uses. It is usually a good idea +to provide version information here so that people can decide whether +fixes for the module are worth downloading. + + +INSTALLATION + +To install this module, run the following commands: + + perl Makefile.PL + make + make test + make install + +SUPPORT AND DOCUMENTATION + +After installing, you can find documentation for this module with the +perldoc command. + + perldoc Map::Splat + +You can also look for information at: + + RT, CPAN's request tracker (report bugs here) + http://rt.cpan.org/NoAuth/Bugs.html?Dist=Map-Splat + + AnnoCPAN, Annotated CPAN documentation + http://annocpan.org/dist/Map-Splat + + CPAN Ratings + http://cpanratings.perl.org/d/Map-Splat + + Search CPAN + http://search.cpan.org/dist/Map-Splat/ + + +LICENSE AND COPYRIGHT + +Copyright (C) 2016 Mark Wells + +This program is free software; you can redistribute it and/or modify it +under the terms of the the Artistic License (2.0). You may obtain a +copy of the full license at: + +L + +Any use, modification, and distribution of the Standard or Modified +Versions is governed by this Artistic License. By using, modifying or +distributing the Package, you accept this license. Do not use, modify, +or distribute the Package, if you do not accept this license. + +If your Modified Version has been derived from a Modified Version made +by someone other than you, you are nevertheless required to ensure that +your Modified Version complies with the requirements of this license. + +This license does not grant you the right to use any trademark, service +mark, tradename, or logo of the Copyright Holder. + +This license includes the non-exclusive, worldwide, free-of-charge +patent license to make, have made, use, offer to sell, sell, import and +otherwise transfer the Package with respect to any patent claims +licensable by the Copyright Holder that are necessarily infringed by the +Package. If you institute patent litigation (including a cross-claim or +counterclaim) against any party alleging that the Package constitutes +direct or contributory patent infringement, then this Artistic License +to you shall terminate on the date that such litigation is filed. + +Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER +AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. +THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY +YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR +CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR +CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/Splat.pm b/Splat.pm new file mode 100644 index 0000000..5729345 --- /dev/null +++ b/Splat.pm @@ -0,0 +1,521 @@ +package Map::Splat; + +use 5.006; +use strict; +use warnings FATAL => 'all'; + +use File::chdir; +use File::Temp qw(tempdir); +use File::Path qw(make_path); +use File::Slurp qw(read_file write_file); +use XML::LibXML::Simple qw(XMLin); +use List::Util qw(min max); +use Data::Dumper; +use Image::Magick; +use Moo; +use POSIX ('floor', 'ceil'); +use v5.10; + +=head1 NAME + +Map::Splat - Wrapper for the Splat! RF propagation modeling tool + +=head1 VERSION + +Version 0.01 + +=cut + +our $VERSION = '0.01'; + +=head1 SYNOPSIS + + use Map::Splat; + + my $foo = Map::Splat->new(); + ... + +=head1 METHODS + +=over 4 + +=cut + +# requires: +# - Splat +# - wget +# - zip +# - gdal-bin package (not used yet, but just wait) +# - XML::LibXML +# - ImageMagick + +my $SRTM_DIR = $ENV{HOME} . '/.splat'; +my $SRTM_PATH = 'http://dds.cr.usgs.gov/srtm/version2_1/SRTM3/North_America'; +my $SPLAT_CMD = '/usr/bin/splat'; + +=item new PARAMETERS + +Constructs a new mapping scenario. This takes the following parameters: + +lon: the tower longitude (east is positive) + +lat: the tower latitude (north is positive) + +height: the tower height above ground level, in feet + +freq: the frequency, in MHz + +h_width: the horizontal beamwidth, in degrees + +v_width: the vertical beamwidth, in degrees + +azimuth: the antenna orientation, in degrees from north (90 = east) + +tilt: the downward tilt of the antenna, in degrees + +and optionally accepts: + +dir: the working directory to use; defaults to a random tempdir + +id: the filename prefix for working files; defaults to '1' + +name: a string describing the tower; defaults to 'Tower' + +min_loss: the lowest path loss level to show on the map; defaults to 80 dB + +max_loss: the highest path loss level to show on the map; defaults to 160 dB + +=cut + +foreach ( qw( lon lat height freq h_width v_width azimuth tilt ) ) { + has $_ => ( is => 'rw', required => 1 ); +} + +has 'dir' => ( + is => 'ro', + default => sub { + tempdir(CLEANUP => 1) + }, +); + +has 'id' => ( + is => 'ro', + default => sub { 1 } +); + +has 'name' => ( + is => 'ro', + default => sub { 'Tower' } +); + +# there are more sophisticated ways to calculate this. for now we just expose +# the ends of the scale as optional parameters. +has 'min_loss' => ( + is => 'ro', + default => sub { 80 } +); + +has 'max_loss' => ( + is => 'ro', + default => sub { 160 } +); + +=item image + +After calling I this will contain an L object with +the raw image data. + +=cut + +has 'image' => ( + is => 'rw', +); + +=item box + +After calling I this will contain a hashref of 'north', 'south', +'east', and 'west' indicating the bounds of the map area. + +=cut + +has 'box' => ( + is => 'rw', + default => sub { +{} } +); + +=item db_colors + +Returns a hashref of (path loss level in dB) => (color level). + +=cut + +sub db_colors { + my $self = shift; + my %color; + # we have 32 color bands; find the width of a single band + my $db_step = ($self->max_loss - $self->min_loss) / 32; + for (my $i = 0; $i < 32; $i++) { + # + 1 here so that the highest band is _above_ the -db switch setting + my $db = ceil($self->max_loss - ($i * $db_step)) + 1; + my $color = 248 - ($i * 8); + $color{$db} = $color; + } + \%color; +} + +sub ew { + my $lon = shift; + $lon < 0 ? 'W' : 'E'; +} + +sub ns { + my $lat = shift; + $lat < 0 ? 'S' : 'N'; +} + +sub debug { + my $self = shift; + my $arg = shift; + if (ref $arg) { + warn Dumper($arg); + } else { + warn "$arg\n"; + } +} + +=item calculate + +Invoke Splat to create a map. Currently, the map will cover the 1-degree +quadrangle containing the tower location. + +=cut + +sub calculate { + my $self = shift; + + my $signed_lat = $self->lat; + my $signed_lon = $self->lon; + + my $id = $self->id; + + local $CWD = $self->dir; + + # write the site file + # note that Splat wants longitude in degrees west, from 0 to <360 + # (this will also matter for SDF files) + my $splat_lon = -1 * $signed_lon; + $splat_lon += 360 if $splat_lon < 0; + + $self->debug("creating QTH file"); + write_file("$id.qth", + $self->name . "\n" . + $signed_lat . "\n" . + $splat_lon . "\n" . + $self->height . "\n" + ); + + # Longley-Rice parameters + my $freq = $self->freq; + my $pol = 1; # polarization = vertical + $self->debug("creating LRP file for $freq MHz"); + + my $lrp = <debug("creating $id.lcf\n"); + my $lcf = ''; + my $colors = $self->db_colors; + for my $db (sort { $a <=> $b } keys %$colors) { + my $red = $colors->{$db}; + $lcf .= "$db: $red, 0, 0\n"; + } + write_file("$id.lcf", $lcf); + + # AZ file: radiation pattern in horizontal plane + # should be able to take this as an input (and kinda can, by overriding + # antenna_pattern) + my $bearing = $self->azimuth; + my $downtilt = $self->tilt; + my ($az, $el) = $self->antenna_pattern; + $self->debug("creating $id.az for bearing $bearing\n"); + + open my $fh, '>', "$id.az"; + printf $fh "%0.1f\n", ($bearing); + foreach my $t (sort { $a <=> $b } keys (%$az)) { + printf $fh "%d\t%0.6f\n", ($t, $az->{$t}); + } + + close $fh; + + # EL file: radiation pattern in vertical plane + $self->debug("creating $id.el for downtilt $downtilt\n"); + open $fh, '>', "$id.el"; + printf $fh "%0.1f\t%0.1f\n", ($downtilt, $bearing); + foreach my $t (sort { $a <=> $b } keys (%$el)) { + printf $fh "%0.1f\t%0.3f\n", ($t, $el->{$t}); + } + close $fh; + + # make sure we have SRTM for the area around the antenna + # ("area around the antenna" should be configurable) + # (and support SRTM1/high def version? only works in North America) + + for (my $dx = -2; $dx <= 2; $dx++) { + for (my $dy = -2; $dy <= 2; $dy++) { + my $splat_lon_east = floor($splat_lon) + $dx; + my $splat_lon_west = ($splat_lon_east + 1) % 360; + my $lat_south = floor($signed_lat) + $dy; + my $lat_north = $lat_south + 1; + + next if $lat_north > 90 or $lat_south < -90; # haha + + # the naming convention used by Splat's SDF files: + # south:north:east:west + # longitude is degrees west, from 0 to 359. + # note that the last one (from 1E to 0W) is 359:0, not 359:360 + my $sdffile = "$SRTM_DIR/$lat_south:$lat_north:$splat_lon_east:$splat_lon_west.sdf"; + if ( ! -f $sdffile ) { + if ( ! -d $SRTM_DIR ) { + make_path($SRTM_DIR); # dies on error + } + local $CWD = $SRTM_DIR; + # the USGS, though, just marks them as N/S and E/W. reference is the + # southwest corner. + # that's the negative of splat longitude, shifted to the range (-180, 180) + # or in the east, it's 360 - splat longitude + my $usgs_lon_west = -1 * $splat_lon_west; + $usgs_lon_west += 360 if $usgs_lon_west < -180; + my $hgtfile = ns($lat_south) . abs($lat_south) . + ew($usgs_lon_west) . abs($usgs_lon_west) . + '.hgt'; + my $zipfile = $hgtfile . '.zip'; + $self->debug("fetching $SRTM_PATH/$zipfile\n"); + my $status = system('wget', "$SRTM_PATH/$zipfile"); + if ( $status > 0 ) { + # normal if the tower location is near a coast, so try to continue + warn "couldn't download $zipfile\n"; + next; + } + $status = system('unzip', $zipfile); + # this isn't normal though + die "couldn't extract $zipfile\n" if $status > 0; + # unfortunately gives no useful output + $status = system('srtm2sdf', $hgtfile); + unlink $hgtfile; + unlink $zipfile; + } + if ( ! -f $sdffile ) { + $self->debug("$sdffile could not be downloaded.\n"); + next; + } + $self->debug("using file $sdffile\n"); + } # $dy + } # $dx + + $self->debug("running Splat...\n"); + my @args = ( + '-d', $SRTM_DIR, + '-t', "$id.qth", # transmitter site + '-o', "$id.ppm", # output file name + '-db', $self->max_loss, # power level range + '-L', '30', # assumed receiver antenna height - XXX should be config + '-R', '10', # maximum coverage radius - XXX should be config + '-ngs', # do not show terrain + '-kml', # generate a KML also + '-N', # suppress noise + '-erp', '0', # transmitter power (only showing relative path loss, so 0) + ); + $self->debug(join(" ", @args) . "\n"); + my $rv = system($SPLAT_CMD, @args); + if ( $rv != 0 ) { + $rv = $rv >> 8; + die "splat command failed ($rv): $!"; + } + + # results now in .kml referencing .ppm. + # pull the .kml apart to find the coordinates + my $kml = XMLin("$id.kml"); + my $latlon = $kml->{'Folder'}->{'GroundOverlay'}->{'LatLonBox'}; + $self->box($latlon); + my $image = Image::Magick->new; + $image->Read("$id.ppm"); + $self->image($image); + # there's a lot we could do with this (GDAL polygonize, etc.) but for + # now just hold onto the output. +} + +=item png + +Returns the rendered map, as a PNG. The path loss data will be in the red +channel, scaled according to the I mapping. + +=cut + +sub png { + my $self = shift; + my $image = $self->image or return; + my $png = $image->Clone; + $png->Set(magick => 'png'); + $png->Transparent('white'); + return $png->ImageToBlob; +} + +=item mask + +Returns the map as a PNG, with solid red in the areas where the path loss is +below I. The rest of the image will be transparent. + +=cut + +sub mask { + my $self = shift; + my $image = $self->image or return; + my $png = $image->Clone; + $png->Set(magick => 'png'); + $png->Threshold(threshold => 254, channel => 'Red'); + $png->Transparent('white'); + return $png->ImageToBlob; +} + +=item box_geometry + +Returns the map area box as a GeoJSON-style geometry object. + +=cut + +sub box_geometry { + my $self = shift; + my $box = $self->box; + { + type => 'Polygon', + coordinates => [ + [ $box->{west}, $box->{south} ], + [ $box->{east}, $box->{south} ], + [ $box->{east}, $box->{north} ], + [ $box->{west}, $box->{north} ], + [ $box->{west}, $box->{south} ], + ], + }; +} + +#internal method; you can subclass and override this to create a different +#antenna pattern. + +sub antenna_pattern { + + my $self = shift; + my $beamwidth = $self->h_width; + + my $falloff = 2; + + my %az = (); + my %el = (); + my $theta = 0; + while ($theta < 360) { + + if ($theta <= ($beamwidth / 2)) { + $az{$theta} = 1.0; + } elsif ($theta >= (360 - ($beamwidth / 2))) { + $az{$theta} = 1.0; + } elsif ($theta > ($beamwidth / 2) and $theta < 180) { + my $x = ($theta - ($beamwidth / 2)) / ($beamwidth / 2); + $az{$theta} = 1+(-($x*$falloff)**2); + $az{$theta} = ($az{$theta} > 0) ? $az{$theta} : 0.001000; + } elsif ($theta < (360 - ($beamwidth / 2)) and $theta > 180) { + my $x = ($theta - (360 - ($beamwidth / 2))) / ($beamwidth / 2); + $az{$theta} = 1+(-(-$x*$falloff)**2); + $az{$theta} = ($az{$theta} > 0) ? $az{$theta} : 0.001000; + } else { + $az{$theta} = 0.001000; + } + + $theta++; + + } + + $beamwidth = $self->v_width; + $theta = -10; + while ($theta <= 90) { + + if (abs($theta) <= ($beamwidth / 2)) { + $el{$theta} = 1.0; + } else { + my $x = (abs($theta) - ($beamwidth / 2)) / ($beamwidth / 2); + $el{$theta} = 1+(-($x*$falloff)**2); + $el{$theta} = ($el{$theta} > 0) ? $el{$theta} : 0.001000; + } + + $theta++; + } + +# while ($theta <= 90) { +# +# if ($theta >= -10 and $theta <= 90) { +# $el{$theta} = 1.0; +# } else { +# $el{$theta} = 0.0; +# } +# +# $theta += 0.5; +# +# } + + return({%az}, {%el}); + +} + +=back + +=head1 AUTHOR + +Mark Wells, C<< >> + +=head1 BUGS + +Currently only works in North America due to a hardcoded download path. + +The antenna radiation patterns are somewhat arbitrary at the moment. + +Please report any bugs or feature requests to C, +or through the web interface at +L. I will be +notified, and then you'll automatically be notified of progress on your bug +as I make changes. + +=head1 SUPPORT + +You can find documentation for this module with the perldoc command. + + perldoc Map::Splat + +=head1 ACKNOWLEDGEMENTS + +John Magliacane (KD2BD) created Splat! and released it under the GNU GPL. + +This library is based in part on code by Kristian Hoffmann of Fire2Wire +Internet Services. + +=head1 LICENSE AND COPYRIGHT + +Copyright 2016 Mark Wells. + +This program is free software; you can redistribute it and/or modify it +under the terms of the the Artistic License (2.0). You may obtain a +copy of the full license at: + +L + +=cut + +1; diff --git a/ignore.txt b/ignore.txt new file mode 100644 index 0000000..4ce34b6 --- /dev/null +++ b/ignore.txt @@ -0,0 +1,18 @@ +Makefile +Makefile.old +Build +Build.bat +META.* +MYMETA.* +.build/ +_build/ +cover_db/ +blib/ +inc/ +.lwpcookies +.last_cover_stats +nytprof.out +pod2htm*.tmp +pm_to_blib +Map-Splat-* +Map-Splat-*.tar.gz diff --git a/t/00-load.t b/t/00-load.t new file mode 100644 index 0000000..fa5caa5 --- /dev/null +++ b/t/00-load.t @@ -0,0 +1,13 @@ +#!perl -T +use 5.006; +use strict; +use warnings FATAL => 'all'; +use Test::More; + +plan tests => 1; + +BEGIN { + use_ok( 'Map::Splat' ) || print "Bail out!\n"; +} + +diag( "Testing Map::Splat $Map::Splat::VERSION, Perl $], $^X" ); diff --git a/t/manifest.t b/t/manifest.t new file mode 100644 index 0000000..6ddfe36 --- /dev/null +++ b/t/manifest.t @@ -0,0 +1,15 @@ +#!perl -T +use 5.006; +use strict; +use warnings FATAL => 'all'; +use Test::More; + +unless ( $ENV{RELEASE_TESTING} ) { + plan( skip_all => "Author tests not required for installation" ); +} + +my $min_tcm = 0.9; +eval "use Test::CheckManifest $min_tcm"; +plan skip_all => "Test::CheckManifest $min_tcm required" if $@; + +ok_manifest(); diff --git a/t/splat.t b/t/splat.t new file mode 100644 index 0000000..53dcac2 --- /dev/null +++ b/t/splat.t @@ -0,0 +1,29 @@ +#!perl +use 5.006; +use strict; +use warnings FATAL => 'all'; +use Test::More; + +plan tests => 2; + +use Map::Splat; +my $map = Map::Splat->new( + lon => -122.279, + lat => 37.939, + height => 300, + freq => 2460, + azimuth => 200, + h_width => 180, + v_width => 20, + tilt => 2, + max_loss => 180, + min_loss => 30, +); +$map->calculate; +ok( defined $map->box, 'bounding box exists' ); +ok( defined $map->png, 'PNG generated' ); + +$map->image->Write('splat.png'); +use File::Slurp 'write_file'; +write_file 'mask.png', $map->mask; + -- 2.11.0