CINXE.COM
Maryland Plant Atlas
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Maryland Plant Atlas</title> <link href="css/bootstrap.min.css" rel="stylesheet"> <link href="css/autocomplete.css" rel="stylesheet"> <link rel="stylesheet" type="text/css" href="css/species_table.css" /> <style type="text/css"> #slideshow { margin-left:8px; border:none; vertical-align:middle; margin-top:-1px; } #taxonLinks { margin: 25px 25px 35px 25px; } .carousel-caption { max-width: 500px; padding: 0 20px; margin:0 auto; margin-top: 200px; text-align:center; } hoverchangeDNE:hover { background-color:#66CCFF; } input { margin-right: 2px; } .tagList { font: 11pt calibri, trebuchet ms; color: #990000; margin-top: 12px } .nav-tabs li a { background-color:#e7e7e7; } .loading-spinner { border: 4px solid #f3f3f3; /* Light grey */ border-top: 4px solid #3498db; /* Blue */ border-radius: 50%; width: 50px; height: 50px; animation: spin 2s linear infinite; } .loading-overlay { position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: rgba(255, 255, 255, 0.7); /* Semi-transparent white background */ display: flex; justify-content: center; align-items: center; z-index: 9999; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } </style> <script type="text/javascript" src="js/jquery-1.11.3.min.js"></script> <script type="text/javascript" src="js/bootstrap.min.js"></script> <script type="text/javascript" src="js/angular.min.js"></script> <script type="text/javascript" src="js/jquery.dataTables.min.js"></script> <script type="text/javascript" src="js/quadCoord.js"></script> <script type="text/javascript" src="js/jquery.colorbox-min.js"></script> <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=AIzaSyAZeauwU5ojse6K5D7wLKbpEJ6oxyd55gs"></script> <script type="text/javascript" src="js/countyCoordNoWater.js"></script> </head> <body class="light" ng-app="" onunload=""> <div class="container"> <!-- Static navbar --> <nav class="navbar navbar-default"> <div class="container-fluid"> <div class="navbar-header"> <span class="navbar-brand" style="margin-top:-8px"><a href="index.php"><img src="images/MPA_20160127_transparent.png" class="img-responsive logo" style="border:none;" /></a></span> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> </div> <div id="navbar" class="navbar-collapse collapse"> <ul class="nav navbar-nav"> <li><a href="index.php">Home</a></li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">About <span class="caret"></span></a> <ul class="dropdown-menu"> <li><a href="about.php">About Us</a></li> <li><a href="partners.php">Partners</a></li> </ul> </li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Explore <span class="caret"></span></a> <ul class="dropdown-menu"> <li><a href="explore.php">Advanced Search</a></li> <li><a href="exploreByFamily.php?kingdom=Plantae">Explore by Family</a></li> <li><a href="viewTopNeedsByQuad.php">Explore Quad Needs</a></li> <li><a href="viewQuadList.php">View Quad Checklists</a></li> <li><a href="quadHeatMap.php">View Quad Heat Map</a></li> <li><a href="quadMap.php">USGS Quad Map</a></li> </ul> </li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Links <span class="caret"></span></a> <ul class="dropdown-menu"> <li><a href="https://www.marylandbiodiversity.com/" target="_blank">Maryland Biodiversity Project</a></li> <li><a href="https://dnr.maryland.gov/Pages/default.aspx" target="_blank">Maryland DNR</a></li> <li><a href="http://www.mdflora.org/" target="_blank">Maryland Native Plant Society</a></li> <li><a href="https://midatlanticherbaria.org/portal/collections/misc/collprofiles.php?collid=332" target="_blank">Norton-Brown Herbarium</a></li> </ul> </li> <li class="dropdown"> <span style="vertical-align:middle"> <form autocomplete="off" onKeyPress="return event.keyCode != 13;"> <input id="autocomplete" class="autocompleteHeader" name="species" value="Search for plants..." onFocus="this.value = '';" style="text-align:left" /> </form> </span> </li> </div><!--/.nav-collapse --> </div><!--/.container-fluid --> </nav> <div id="upper" style="width:980px;min-height:400px; margin-left:10px; margin-right:10px; margin-top:20px;"> <span ng-controller="getSpeciesTaxonomyController"> <span ng-repeat="x in names"> <h3><em><b>{{ x.FullName }}</em> </b>{{ x.RankAuthor }} - {{ x.Common_Name }}</h3> <a href='viewChecklist.php?kingdom=?{{ x.Kingdom }}'>{{ x.Kingdom }}</a> > <a href='viewChecklist.php?class=?{{ x.Class }}'>{{ x.Class }}</a> > <a href='viewChecklist.php?order=?{{ x.OrderName }}'>{{ x.OrderName }}</a> > <a href='viewChecklist.php?family=?{{ x.Family }}'>{{ x.Family }}</a> > <a href='viewChecklist.php?genus=?{{ x.Genus }}'>{{ x.Genus }}</a><br /> </span> <div ng-controller="getSpeciesSynonymController" style="width:950px; margin-top:12px;" align="left"> <span style="margin-top:5px">Synonyms: </span> <span ng-if="synonyms.length != 0" ng-repeat="y in synonyms"> <!--<p ng-bind-html="x.Synonym" id = "Synonym"></p><br/>--> <span ng-if="y.IsScientific == '1'"><em>{{ y.Synonym }}</em>{{$last ? '.' : ', '}}</span> <span ng-if="y.IsScientific != '1'">{{ y.Synonym }}{{$last ? '.' : ', '}}</span> </span> <span ng-if="synonyms.length === 0"> <em>None recorded.</em> </span> <div class='tagList'><span class='tagList'>Non-native</span></div> </div> </span> <!--Maps with tabs to toggle between county/quad--> <div id="map-container" style="margin-top:25px;margin-right:0px"> <div style="float:right;margin-right:-35px;margin-top:50px;padding-left:4px;min-width:50px"> <b>Legend</b><br/> <div style = "float:left;height:10px;width:10px;margin-top:5px;border: 1px solid #5f19a2 ; background-color: #ffc7e9;"></div><div style = "float:left"> 1</div><br/> <div style = "float:left;height:10px;width:10px;margin-top:5px;border: 1px solid #5f19a2 ;background-color: #e586d7;"></div><div style = "float:left"> 2-3</div><br/> <div style = "float:left;height:10px;width:10px;margin-top:5px;border: 1px solid #5f19a2 ;background-color:#c358cd ;"></div><div style = "float:left"> 4-9</div><br/> <div style = "float:left;height:10px;width:10px;margin-top:5px;border: 1px solid #5f19a2 ;background-color: #993aba ;"></div><div style = "float:left"> 10-27</div><br/> <div style = "float:left;height:10px;width:10px;margin-top:5px;border: 1px solid #330590 ;background-color: #6d20a8;"></div><div style = "float:left"> 28-84</div><br/> <div style = "float:left;height:10px;width:10px;margin-top:5px;border: 1px solid #25008a ;background-color: #420b96 ;"></div><div style = "float:left"> 85+</div><br/> </div> <div style = "float:left"> <!-- Map tabs --> <ul class="nav nav-tabs" role="tablist"> <li role="presentation"><a href="#countyframe" role="tab" data-toggle="tab"><b>County Map</b></a></li> <li role="presentation" class="active"><a href="#quadrantframe" role="tab" data-toggle="tab"><b>Quad Map</b></a></li> </ul> <!-- Map content---> <div class="tab-content"> <div id='countyframe' role="tabpanel" class="tab-pane fade"> <div id="map-canvas2" style="width: 950px; height: 450px" class="tab-pane" ></div> <div id="record-count-county"></div> </div> <div id='quadrantframe' role="tabpanel" class="tab-pane fade in active"> <div id="map-canvas" style="width: 950px; height: 450px" class="tab-pane active" > <!-- Overlay Spinner --> <div ng-show="isLoading" class="loading-overlay"> <div class="loading-spinner">{{isLoading}}</div> </div> </div> <div id="record-count"></div> </div> </div> <span ng-controller="TypeFilter"> Mapped Record Types: <span ng-repeat="item in allOptions" style="padding-right:10px" class="item" id="{{item.id}}"><input type="checkbox" ng-change="sync(bool, item)" ng-model="bool" ng-checked="isChecked(item.id)"> {{item.id}} </span> </span> </div> </div> <!-- Images --> <div id="upper-2" style="width:100%; margin-top:180px;"> <!---Bootstrap Image Carousel!---> <div id="myCarousel" class="carousel slide" style="width:950px;float:left;margin-top:20px; margin-bottom:20px" data-ride="" ng-controller="getSpeciesImagesController"> <h4>Images</h4> <span ng-if="images.length != 0"> <div class="carousel-inner" role="listbox" style="height:450px; width:950px; border: 1px solid #333; text-align:center; background-color:#4F4F4F"> <div class="item" ng-class="{active : !$index}" ng-repeat="img in images" style="margin: 0 auto; width:950px; text-align:center"> <img ng-src="{{img.Location}}" style="margin: 0 auto; max-height: 450px; max-width: 1024px" alt="{{img.Caption}}"> <div class="carousel-caption" style="width:900px; background-color: #444; text-align:center; padding:8px; opacity: 0.9; border-radius: 12px; margin-top: 150px; text-align:center"><span ng-bind-html="img.Caption"></span> Photo by <a href="{{img.Photographer_Site}}" target="_blank">{{img.FirstName}} {{img.LastName}}</a>.</div> </div> <a class="left carousel-control" href="#myCarousel" role="button" data-slide="prev"> <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span> <span class="sr-only">Previous</span> </a> <a class="right carousel-control" href="#myCarousel" role="button" data-slide="next"> <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span> <span class="sr-only">Next</span> </a> </div> </span> <span ng-if="images.length === 0"> <br/><br/><br/><h2>No Images Available</h2> </span> </div> <div id="lower" style="width:9500px; margin-left:10px; padding-top:15px; padding-bottom:50px; clear:both"> <h4>Selected Links</h4> <div id="taxonLinks"> <p><li><a href='http://www.marylandbiodiversity.com/view/3766' target='_blank' class='darkerText'>View at Maryland Biodiversity Project</a></li></p><p><li><a href='http://beta.floranorthamerica.org/Thymus_pulegioides' target='_blank' class='darkerText'>Search Flora of North America</a></li></p><p><li><a href=' https://midatlanticherbaria.org/portal/collections/list.php?state=Maryland&taxa=Thymus+pulegioides&usethes=1&taxontype=2&tabindex=1' target='_blank' class='darkerText'>Search Mid-Atlantic Herbaria Consortium</a></li></p><p><li><a href=' https://midatlanticherbaria.org/portal/collections/list.php?db=332&state=Maryland&taxa=Thymus+pulegioides&usethes=1&taxontype=2&tabindex=1' target='_blank' class='darkerText'>Search Norton-Brown Herbarium</a></li></p><p><li><a href='https://www.inaturalist.org/taxa/Thymus pulegioides' target='_blank'>View taxon at iNaturalist</a></li></p><p><li><a href='https://explorer.natureserve.org/Taxon/ELEMENT_GLOBAL.2.159729/Thymus_pulegioides' target='_blank' class='darkerText'>View taxon at NatureServe</a></li></p><p><li><a href='https://www.google.com/search?q=Thymus+pulegioides&tbm=isch' target='_blank' class='darkerText'>Search Google Images</a></li></p> </div> <!-- end taxon links --> <h4>Records</h4> <input name="test" type="radio" ng-model="recordsort" value="type" ng-checked="true" class="active radio-inline" checked="checked"> Sort by Type <input name="test" type="radio" ng-model="recordsort" value="county" class="radio-inline"> Sort by County<br> <div ng-controller="getRecordDataController" style="width:800px; margin-left:10px; margin-top:0px;" align="left" ng-switch="recordsort"> <!--COUNTY SORT --------------------------------------------------------------------------------------------------------------------------------------------------------> <span ng-switch-when="county"> <div ng-repeat="c in countylist"><br/> <span ng-if="c.CountyName == 'Baltimore City'"><h4>{{c.CountyName}}</h4></span> <span ng-if="c.CountyName != 'Baltimore City'"><h4>{{c.CountyName}}</h4></span> <!--<span ng-if="c.CountyName != 'Baltimore City'"><h4>{{c.CountyName}} County</h4></span>--> <span ng-if="c.specimens === undefined && c.photos === undefined && c.observations === undefined && c.publications === undefined"><i> No records</i></span> <table ng-if="c.specimens === undefined"> <!--<tr><td><i>No specimens recorded for this species</i></td></tr>--> </table> <span ng-if="c.specimens !== undefined"> <table class="table table-condensed records hoverchange" > <tr><th style = "width:200px" colspan = 2><b>Specimens</b><th style = "width:200px" colspan = 2>Record Count: {{c.specimens.count}}<th style = "width:100px"><button onclick = "changeButton(this);" type="button" class="btn-xs btn-primary testclass" data-toggle="collapse" data-target=".spcol{{$index}}">Expand</button></td></tr> </table> <table class="table table-condensed records" id = "specimenTable" class = ""> <tr class = "collapse individual spcol{{$index}} "> <!--<th style = "width:100px">    </th>--> <th style = "width:200px; padding-left:20px">Collection</th> <th style = "width:200px">RecordID</th> <th style = "width:100px">Link</th> <th style = "width:100px">Date</th> </tr> <tr ng-repeat="j in c.specimens.records" class = "collapse individual spcol{{$parent.$index}} "> <!--<td style = "width:100px"> • </td>--> <td style = "width:200px; padding-left:20px">{{j.FirstName}} {{j.LastName}}</td> <td style = "width:200px">{{j.RecordID}}</td> <td style = "width:100px" ng-if="j.Person_ID != '1276'"><a href="https://www.marylandbiodiversity.com/view/{{j.Species_ID}}" target="_blank">View MBP species page</a></td> <td style = "width:100px" ng-if="j.Person_ID == '1276'"><a href="http://www.nbh.psla.umd.edu/detail.php?ID={{j.SourceID}}">View NBH Record</a></td> <td style = "width:100px"> <span ng-if="j.Month != '0'">{{j.Month}}/</span><span ng-if="j.Day != '0'">{{j.Day}}/</span><span ng-if="j.Year != '0'">{{j.Year}}</span> </td> </tr> </table> </span> <table ng-if="c.observations === undefined"> <!-- <tr><td><i>No observations recorded for this species</i></td></tr>--> </table> <span ng-if="c.observations !== undefined"> <table class="table table-condensed records hoverchange" > <tr><th style = "width:200px" colspan = 2><b>Observations</b><th style = "width:200px" colspan = 2>Record Count: {{c.observations.count}}<th style = "width:100px"><button onclick = "changeButton(this);" type="button" class="btn-xs btn-primary testclass" data-toggle="collapse" data-target=".recol{{$index}}">Expand</button></td></tr> </table> <table class="table table-condensed records" id = "observationsTable" class = ""> <tr class = "collapse individual recol{{$index}} "> <!--<th style = "width:100px">    </th>--> <th style = "width:200px; padding-left:20px">Observer</th> <th style = "width:200px">RecordID</th> <th style = "width:100px">Link</th> <th style = "width:100px">Date</th> </tr> <tr ng-repeat="j in c.observations.records" class = "collapse individual recol{{$parent.$index}} "> <!--<td style = "width:100px"> • </td>--> <td style = "width:200px; padding-left:20px">{{j.FirstName}} {{j.LastName}}</td> <td style = "width:200px">{{j.RecordID}}</td> <td style = "width:100px" ng-if="j.Person_ID != '1276'"><a href="https://www.marylandbiodiversity.com/view/{{j.Species_ID}}" target="_blank">View MBP species page</a></td> <td style = "width:100px" ng-if="j.Person_ID == '1276'"><a href = "http://www.nbh.psla.umd.edu/detail.php?ID={{j.SourceID}}">View NBH Record</a></td> <td style = "width:100px"> <span ng-if="j.Month != '0'">{{j.Month}}/</span><span ng-if="j.Day != '0'">{{j.Day}}/</span><span ng-if="j.Year != '0'">{{j.Year}}</span> </td> </tr> </table> </span> <table ng-if="c.publications === undefined"> <!--<tr><td><i>No publications recorded for this species</i></td></tr>--> </table> <span ng-if="c.publications !== undefined"> <table class="table table-condensed records hoverchange" > <tr><th style = "width:200px" colspan = 2><b>Publications</b><th style = "width:200px" colspan = 2>Record Count: {{c.publications.count}}<th style = "width:100px"><button onclick = "changeButton(this);" type="button" class="btn-xs btn-primary testclass" data-toggle="collapse" data-target=".pucol{{$index}}">Expand</button></td></tr> </table> <table class="table table-condensed records" id = "publicationsTable" class = ""> <tr class = "collapse individual pucol{{$index}} "> <!--<th style = "width:100px">    </th>--> <th style = "width:200px; padding-left:20px">Publisher</th> <th style = "width:200px">RecordID</th> <th style = "width:100px">Link</th> <th style = "width:100px">Date</th> </tr> <tr ng-repeat="j in c.publications.records" class = "collapse individual pucol{{$parent.$index}} "> <!--<td style = "width:100px"> • </td>--> <td style = "width:200px; padding-left:20px">{{j.FirstName}} {{j.LastName}}</td> <td style = "width:200px">{{j.RecordID}}</td> <td style = "width:100px" ng-if="j.Person_ID != '1276'"><a href="https://www.marylandbiodiversity.com/view/{{j.Species_ID}}" target="_blank">View MBP species page</a></td> <td style = "width:100px" ng-if="j.Person_ID == '1276'"><a href = "http://www.nbh.psla.umd.edu/detail.php?ID={{j.SourceID}}">View NBH Record</a></td> <td style = "width:100px"> <span ng-if="j.Month != '0'">{{j.Month}}/</span><span ng-if="j.Day != '0'">{{j.Day}}/</span><span ng-if="j.Year != '0'">{{j.Year}}</span> </td> </tr> </table> </span> </div> </span> <!--TYPE SORT----------------------------------------------------------------------------------------------------------------------------------------------> <span ng-switch-default> <br/><b style = "font-size:115%">Specimens</b><br/><br/> <table ng-if="specimen === undefined"> <tr><td><i>No specimens recorded for this species</i></td></tr> </table> <table class="table table-condensed records" ng-if="specimen !== undefined"> <tr><th style = "width:400px" colspan = 3>Source</th><th style = "width:300px">Record Count</th><th style = "width:100px">Details</th></tr> </table> <table class="table table-condensed records" id = "specimenTable" ng-repeat="i in specimen | orderBy:'-name':true"> <tr> <td style = "width:400px" colspan = 2 ng-bind-html="renderHtml(i.name)"></td><td style = "width:300px" colspan = 2>{{i.count}}</td><td style = "width:100px"><button onclick = "changeButton(this);" type="button" class="btn-xs btn-primary testclass" data-toggle="collapse" data-target=".spcol{{i.ID}}">Expand</button></td></tr> <tr class = "collapse spcol{{i.ID}} individual" > <!--<th style = "width:100px">    </th>--> <th style = "width:200px; padding-left:20px">County</th> <th style = "width:200px">Quad</th> <th style = "width:100px">Link</th> <th style = "width:100px">Date</th> </tr> <tr ng-repeat="j in i.records | orderBy:['County','QuadName']" class = "collapse spcol{{i.ID}} individual" > <!--<td style = "width:100px"> • </td>--> <td style = "width:200px; padding-left:20px" ng-if="j.County == 'Baltimore City'">{{j.County}}</td> <td style = "width:200px; padding-left:20px" ng-if="j.County != 'Baltimore City'">{{j.County}}</td> <td style = "width:200px" ng-if="vulnerable === true"><i>not displayed</i></td> <td style = "width:200px" ng-if="vulnerable === false">{{j.QuadName}}</td> <td style = "width:100px" ng-if="j.Person_ID != '1276'"><a href="https://www.marylandbiodiversity.com/view/{{j.Species_ID}}" target="_blank">View MBP species page</a></td> <td style = "width:100px" ng-if="j.Person_ID == '1276'"><a href = "http://www.nbh.psla.umd.edu/detail.php?ID={{j.SourceID}}">View NBH Record</a></td> <td style = "width:100px"> <span ng-if="j.Month != '0'">{{j.Month}}/</span><span ng-if="j.Day != '0'">{{j.Day}}/</span><span ng-if="j.Year != '0'">{{j.Year}}</span> </td> </tr> </table> <br/><b style = "font-size:115%">Publications</b><br/><br/> <table ng-if="publication === undefined"> <tr><td><i>No publications recorded for this species</i></td></tr> </table> <table class="table table-condensed records" ng-if="publication !== undefined"> <tr><th style = "width:400px" colspan = 3>Source</th><th style = "width:300px">Record Count</th><th style = "width:100px">Details</th></tr> </table> <table class="table table-condensed records" id = "publicationTable" ng-if="publication" ng-repeat="i in publication | orderBy:'-name':true"> <tr> <td style = "width:400px" colspan = 2 ng-bind-html="renderHtml(i.name)"></td><td style = "width:300px">{{i.count}}</td><td style = "width:100px"><button type="button" onclick = "changeButton(this);" class="btn-xs btn-primary" data-toggle="collapse" data-target=".pucol{{i.ID}}">Expand</button></td></tr> <tr class = "collapse pucol{{i.ID}} individual" > <!--<th style = "width:100px">    </th>--> <th style = "width:200px; padding-left:20px">County</th> <th style = "width:200px">Quad</th> <th style = "width:100px">Date</th> </tr> <tr ng-repeat="j in i.records | orderBy:['County','QuadName']" class = "collapse pucol{{i.ID}} individual" > <!--<td style = "width:100px"> • </td>--> <td style = "width:200px; padding-left:20px" ng-if="j.County == 'Baltimore City'">{{j.County}}</td> <td style = "width:200px; padding-left:20px" ng-if="j.County != 'Baltimore City'">{{j.County}}</td> <td style = "width:200px" ng-if="vulnerable === true"><i>not displayed</i></td> <td style = "width:200px" ng-if="vulnerable === false">{{j.QuadName}}</td> <td style = "width:100px"> <span ng-if="j.Month != '0'">{{j.Month}}/</span><span ng-if="j.Day != '0'">{{j.Day}}/</span><span ng-if="j.Year != '0'">{{j.Year}}</span> </td> </tr> </table> <br/><b style = "font-size:115%">Observations</b><br/><br/> <table ng-if="observation === undefined"> <tr><td><i>No observations recorded for this species</i></td></tr> </table> <table class="table table-condensed records" ng-if="observation !== undefined"> <tr><th style = "width:400px" colspan = 3>Source</th><th style = "width:300px">Record Count</th><th style = "width:100px">Details</th></tr> </table> <table class="table table-condensed records" id="observationTable" ng-repeat="i in observation | orderBy:'-name':true"> <tr> <td style = "width:400px" colspan = 2 ng-bind-html="renderHtml(i.name)"></td><td style = "width:300px">{{i.count}}</td><td style = "width:100px"><button onclick = "changeButton(this);" type="button" class="btn-xs btn-primary" data-toggle="collapse" data-target=".recol{{i.ID}}">Expand</button></td></tr> <tr class = "collapse recol{{i.ID}} individual" > <!--<th style = "width:100px">    </th>--> <th style = "width:200px; padding-left:20px">County</th> <th style = "width:200px">Quad</th> <th style = "width:300px">More info</th> <th style = "width:100px">Date</th> </tr> <tr ng-repeat="j in i.records | orderBy:['County','QuadName']" class = "collapse recol{{i.ID}} individual" > <!--<td style = "width:100px"> • </td>--> <td style = "width:200px; padding-left:20px" ng-if="j.County == 'Baltimore City'">{{j.County}}</td> <td style = "width:200px; padding-left:20px" ng-if="j.County != 'Baltimore City'">{{j.County}}</td> <td style = "width:200px" ng-if="vulnerable === true"><i>not displayed</i></td> <td style = "width:200px" ng-if="vulnerable === false">{{j.QuadName}}</td> <td style = "width:300px"><a href="https://www.marylandbiodiversity.com/view/{{j.Species_ID}}" target="_blank">View MBP species page</a></td> <td style = "width:100px"> <span ng-if="j.Month != '0'">{{j.Month}}/</span><span ng-if="j.Day != '0'">{{j.Day}}/</span><span ng-if="j.Year != '0'">{{j.Year}}</span> </td> </tr> </table> </span> </div> </div> <script type="text/javascript" src="js/mdbAutocomplete.js"></script> <script type="text/javascript" src="js/ajax.js"></script> <script type="text/javascript"> $('#autocompleteHeader').focus(function() { repositionResultsDiv(); }); </script> <script> var typeFilter = []; // Pass the GET param to JavaScript species = '3766'; vulnerable = false; // Call the web service function getSpeciesTaxonomyController($scope,$http) { $http.get("https://www.marylandplantatlas.org/services/getSpeciesData.php?species=" + species) .success(function(response) { $scope.names = response; }); } function getSpeciesSynonymController($scope,$sce,$http) { $http.get("https://www.marylandplantatlas.org/services/getSynonyms.php?species=" + species) .success(function(response) {$scope.synonyms = response; angular.forEach($scope.synonyms,function(value,index){ if(value.IsScientific == 1){ //value.Synonym = $sce.trustAsHtml('<em>' + value.Synonym + '</em>'); } }) }); } species = '3766'; var records = []; function getSpeciesImagesController($scope, $http, $sce) { $http.get("https://www.marylandplantatlas.org/services/getSpeciesImages.php?species=" + species) .success(function(response) {$scope.images = response; for (var i = 0; i < $scope.images.length; i++){ $scope.images[i]['Caption'] = $sce.trustAsHtml($scope.images[i]['Caption']); } }); } // Get the species record data function getRecordDataController($scope, $sce, $http) { // Initialize loading state $scope.isLoading = true; $http.get("https://www.marylandplantatlas.org/services/getRecordData_MARY.php?species=" + species) .then(function(response) { // console.log("Success:", response.data); var grouped = response.data.grouped; records = response.data.records; // Function to convert object to array to utilize Angular sort feature function ObjToArr(current) { var output = []; for (var key in current) { if (current.hasOwnProperty(key)) { var tempObj = current[key]; output.push(tempObj); } } return output; } $scope.observation = ObjToArr(grouped.Observations); $scope.specimen = ObjToArr(grouped.Specimen); $scope.publication = ObjToArr(grouped.Publications); // $scope.photo = ObjToArr(grouped.Photos); $scope.vulnerable = vulnerable; initialize(); getRecords(records, typeFilter, false); mapRecords(false); $scope.records = records; $scope.renderHtml = function(html_code) { return $sce.trustAsHtml(html_code); }; $scope.countylist = response.data.countylist; $scope.sortType = 'name'; // Dismiss the loading spinner after data is processed $scope.isLoading = false; }) .catch(function(error) { console.error("Error fetching data:", error); // Log more details or handle error appropriately // Optionally, notify the user of the error in a user-friendly manner $scope.isLoading = false; }); } //change record button text onclick function changeButton(button){ if($(button).text() == 'Expand'){ $(button).text('Collapse'); }else{ $(button).text('Expand'); } } //re-map once toggled $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) { e.preventDefault(); $(this).tab('show'); initialize(); mapRecords(true); }) //Trying a new method of controlling checkboxes. Code mostly by Paul B. Hartzog function TypeFilter($scope,$sce){ $scope.isChecked = function(id){ var nomatch = true; for(var i=0 ; i < $scope.data.length; i++) { if($scope.data[i].id == id){ nomatch = false; } } return nomatch; }; $scope.sync = function(bool, item){ if(bool){ for(var i=0 ; i < $scope.data.length; i++) { if($scope.data[i].id == item.id){ $scope.data.splice(i,1); } } } else { // add item $scope.data.push(item); // remove item } typeFilter = $scope.data; getRecords(records, typeFilter, true); mapRecords(true); }; $scope.allOptions = [{ "id": "Specimens", "data": "specimen",}, // {"id": "Photos","data": "photo",}, { "id": "Publications","data": "publication",}, { "id": "Observations","data": "observation",}]; $scope.data = []; } </script> </div> <script type="text/javascript"> //globals var infoWindow = new google.maps.InfoWindow({disableAutoPan: true, maxWidth: 200, FontSize:"80%"}); var map; var latlng; var quads = []; var gm = google.maps; //var counties = []; var counties = [ {"name":"allegany","recordCount":0,"specimen":0,"observation":0,"publication":0,"fullName":"Allegany"}, {"name":"annearundel","recordCount":0,"specimen":0,"observation":0,"publication":0,"fullName":"Anne Arundel"}, {"name":"baltimore","recordCount":0,"specimen":0,"observation":0,"publication":0,"fullName":"Baltimore"}, {"name":"baltimorecity","recordCount":0,"specimen":0,"observation":0,"publication":0,"fullName":"Baltimore City"}, {"name":"calvert","recordCount":0,"specimen":0,"observation":0,"publication":0,"fullName":"Calvert"}, {"name":"caroline","recordCount":0,"specimen":0,"observation":0,"publication":0,"fullName":"Caroline"}, {"name":"carroll","recordCount":0,"specimen":0,"observation":0,"publication":0,"fullName":"Carroll"}, {"name":"cecil","recordCount":0,"specimen":0,"observation":0,"publication":0,"fullName":"Cecil"}, {"name":"charles","recordCount":0,"specimen":0,"observation":0,"publication":0,"fullName":"Charles"}, {"name":"dorchester","recordCount":0,"specimen":0,"observation":0,"publication":0,"fullName":"Dorchester"}, {"name":"frederick","recordCount":0,"specimen":0,"observation":0,"publication":0,"fullName":"Frederick"}, {"name":"garrett","recordCount":0,"specimen":0,"observation":0,"publication":0,"fullName":"Garrett"}, {"name":"harford","recordCount":0,"specimen":0,"observation":0,"publication":0,"fullName":"Harford"}, {"name":"howard","recordCount":0,"specimen":0,"observation":0,"publication":0,"fullName":"Howard"}, {"name":"kent","recordCount":0,"specimen":0,"observation":0,"publication":0,"fullName":"Kent"}, {"name":"montgomery","recordCount":0,"specimen":0,"observation":0,"publication":0,"fullName":"Montgomery"}, {"name":"princegeorges","recordCount":0,"specimen":0,"observation":0,"publication":0,"fullName":"Prince George's"}, {"name":"queenannes","recordCount":0,"specimen":0,"observation":0,"publication":0,"fullName":"Queen Anne's"}, {"name":"somerset","recordCount":0,"specimen":0,"observation":0,"publication":0,"fullName":"Somerset"}, {"name":"stmarys","recordCount":0,"specimen":0,"observation":0,"publication":0,"fullName":"St. Mary's"}, {"name":"talbot","recordCount":0,"specimen":0,"observation":0,"publication":0,"fullName":"Talbot"}, {"name":"washington","recordCount":0,"specimen":0,"observation":0,"publication":0,"fullName":"Washington"}, {"name":"wicomico","recordCount":0,"specimen":0,"observation":0,"publication":0,"fullName":"Wicomico"}, {"name":"worcester","recordCount":0,"specimen":0,"observation":0,"publication":0,"fullName":"Worcester"}]; var coutline = []; var outlinemapped = false; function CenterControl(controlDiv, map) { // Set CSS for the control border. var controlUI = document.createElement('div'); controlUI.style.backgroundColor = '#CCFFE6'; controlUI.style.border = '2px solid #8AE6B8'; controlUI.style.borderRadius = '3px'; controlUI.style.boxShadow = '0 2px 6px rgba(0,0,0,.3)'; controlUI.style.cursor = 'pointer'; controlUI.style.marginLeft = '5px'; controlUI.style.textAlign = 'center'; controlUI.title = 'Click to resize the map'; controlDiv.appendChild(controlUI); // Set CSS for the control interior. var controlText = document.createElement('div'); controlText.style.color = 'rgb(25,25,25)'; controlText.style.fontFamily = 'Roboto,Arial,sans-serif'; controlText.style.fontSize = '16px'; controlText.style.lineHeight = '38px'; controlText.style.paddingLeft = '5px'; controlText.style.paddingRight = '5px'; controlText.style.border = '10px'; // controlText.innerHTML = 'Enlarge'; // controlUI.appendChild(controlText); controlUI.addEventListener('click', function() { if(countySize == 'small'){ $('#map-canvas2').css({"margin-left":"-400px", "width": "950px", "height": "475px"}); google.maps.event.trigger(map2, "resize"); $('#map-canvas').css({"margin-left":"-400px", "width": "950px", "height": "475px"}); this.innerHTML="Reduce"; this.style.color = 'rgb(25,25,25)'; this.style.fontFamily = 'Roboto,Arial,sans-serif'; this.style.fontSize = '16px'; this.style.lineHeight = '38px'; this.style.paddingLeft = '5px'; this.style.paddingRight = '5px'; map2.setZoom(10); map.setZoom(10); // google.maps.event.trigger(map, "resize"); map.setCenter({ lat: 38.83, lng: -77.2138}); map2.setCenter({ lat: 38.83, lng: -77.2138}); countySize = 'big'; }else{ $('#map-canvas2').css({"margin-left":"0px", "width": "450px", "height": "250px"}); google.maps.event.trigger(map2, "resize"); $('#map-canvas').css({"margin-left":"-0px", "width": "450px", "height": "250px"}); map.setZoom(7); map2.setZoom(7); google.maps.event.trigger(map, "resize"); map.setCenter({ lat: 38.83, lng: -77.2138}); map2.setCenter({ lat: 38.83, lng: -77.2138}); // this.innerHTML="Enlarge"; this.style.color = 'rgb(25,25,25)'; this.style.fontFamily = 'Roboto,Arial,sans-serif'; this.style.fontSize = '16px'; this.style.lineHeight = '38px'; this.style.paddingLeft = '5px'; this.style.paddingRight = '5px'; // countySize = 'small'; } }); } //Initialize Map function initialize() { var mapOptions = { center: { lat: 38.83, lng: -77.2138}, mapTypeControlOptions: { style: google.maps.MapTypeControlStyle.HORIZONTAL_BAR, position: google.maps.ControlPosition.BOTTOM_LEFT }, zoomControlOptions: { position: google.maps.ControlPosition.TOP_RIGHT }, zoom: 8 }; if(countySize == 'big'){ mapOptions = { center: { lat: 38.83, lng: -77.2138}, zoom: 8 }; } map = new gm.Map(document.getElementById('map-canvas'), mapOptions); map2 = new gm.Map(document.getElementById('map-canvas2'), mapOptions); var centerControlDiv = document.createElement('div'); var centerControlDiv2 = document.createElement('div'); var centerControl = new CenterControl(centerControlDiv, map); var centerControl2 = new CenterControl(centerControlDiv2, map2); centerControlDiv.index = 1; centerControlDiv2.index = 1; map.controls[google.maps.ControlPosition.LEFT_BOTTOM].push(centerControlDiv); map2.controls[google.maps.ControlPosition.LEFT_BOTTOM].push(centerControlDiv2); } // google.maps.event.addDomListener(window, 'load', initialize); //get record data from controller function, which also calls this function. //###Doesn't seem very logical / efficient to have the call in that controller though //###function needs to be broken down into more modular functions for other maps function getRecords(records, typeFilter, reMap){ if(reMap === true){ for (var i=0; i<counties.length; i++) { counties[i].mapped.setMap(null); counties[i]["recordCount"]=0; counties[i]["specimen"]=0; counties[i]["observation"]=0; counties[i]["publication"]=0; } for (var i=0; i<quads.length; i++) { quads[i].mapped.setMap(null); } } quads = []; var found = 0; var missing = 0; var foundCo = 0; var missingCo = 0; var filtered = 0; //get records from specimenDataController (find another source?) and compile into a quad array //###Should this be done server side in getRecordData.php? for (var i=0; i<records.length; i++) { var current = records[i]; var toFilter = false; for (var j=0; j<typeFilter.length; j++) { if(typeFilter[j]['data'] == current.Type){ toFilter = true; filtered++; continue; } } if(toFilter === true){ continue; } //#################new county stuff if((current.County !== null)&&(current.County != "")){ var county = current.County.toLowerCase(); county = county.replace(/\W+/g, ""); var countyinfo = current.RecordID + ". " + current.FirstName + " " + current.LastName; var coexists = 'no'; for (var j=0; j<counties.length; j++) { if(counties[j]['name'] == county){ counties[j]['recordCount']++; counties[j][current.Type]++; //counties[j]['info'] += "<br/>" + current.RecordID + ": " + current.FirstName + " " + current.LastName; coexists = 'yes'; break; } } if(coexists == 'no'){ //var newcounty = {"name":county,"recordCount":1,"info":"<b>"+countyinfo+":</b><br/>"+info}; var newcounty = {"name":county,"recordCount":1,"recordCount":1,"specimen":0,"observation":0,"publication":0,"fullName":current.County}; newcounty[current.Type]++; counties.push(newcounty); } foundCo++; }else{ missingCo++; } totalRecords = found + missing; $("#record-count").html("Total Records: <b>" + totalRecords.toLocaleString() + "</b>"); //#################end county// //loop through records and create an array of quads by name and record count if((records[i].Quad !== null)&&(records[i].Quad != "")&&(records[i].CrossesQuad != 1)){ if(vulnerable === false){ latlng = new gm.LatLng(records[i].Lat, records[i].Lon); var quad = current.Quad; //old infobox info //var info = current.RecordID + ". " + current.County + ", " + current.FirstName + " " + current.LastName; var exists = 'no'; for (var j=0; j<quads.length; j++) { if(quads[j]['name'] == quad){ quads[j]['recordCount']++; //old infobox info //quads[j]['info'] += "<br/>" + current.RecordID + ": " + current.County + ", " + current.FirstName + " " + current.LastName; quads[j][current.Type]++; exists = 'yes'; break; } } if(exists == 'no'){ //var newquad = {"name":quad,"recordCount":1,"info":"<b>"+quad+":</b><br/>"+info}; var newquad = {"name":quad,"recordCount":1,"specimen":0,"observation":0,"publication":0}; newquad[current.Type]++; quads.push(newquad); } found++; } }else{ missing++; } totalRecords = found + missing; $("#record-count").html("Total Records: <b>" + totalRecords.toLocaleString() + "</b>"); } } //separate map function to be run when switching between map types OBSELETE - REMOVE var countySize = 'small'; var quadSize = 'small'; function mapRecords(reMap){ //create quad polygons var fill = "#F6CEF5"; var stroke = "#F28AF0"; if(quads.length == 0){ infoWindow.setContent("<div style = 'width:100%;max-width:200px; height:60px;overflow;visible;text-align:center'>No Quadrangle<br/> Coordinates <br/>Available</div>"); var latlng = new gm.LatLng(38.901222, -77.265260); infoWindow.setPosition(latlng); infoWindow.open(map); }else{ infoWindow.close(); } // more new county stuff, mirror of quad stuff for now var fill = "#F6CEF5"; var stroke = "#F28AF0"; for (var i=0; i<counties.length; i++) { var countycoords = getCountyCoord(counties[i]['name']); var info = "<span style = 'font-size:110%'><b>"+counties[i]['fullName']+"</b></span>"; if(reMap !== true){ coutline[i] = new gm.Polygon({ paths:countycoords, strokeColor: "#4201B0", strokeOpacity: 0.3, strokeWeight: 1, fillColor: "#ffffff", fillOpacity: 0 }); coutline[i].setMap(map); } if(counties[i]['recordCount'] == 0){ info +=" - <i>No Records</i>"; stroke = '#25008a'; counties[i].mapped = new gm.Polygon({ paths:countycoords, strokeColor: stroke, strokeOpacity: 0.9, strokeWeight: 1, fillOpacity: 0 }); }else{ info += "      <b>"+counties[i]['recordCount']+" Records</b> <br/>Specimens: "+counties[i]['specimen']+"     Observations: "+counties[i]['observation']+"<br/>Publications: "+counties[i]['publication']+" "; if(counties[i]['recordCount'] == 1){ fill = '#ffc7e9'; //stroke = '#DF7ad6'; stroke = '#5f19a2'; }else if(counties[i]['recordCount'] < 4){ fill = '#e586d7'; //stroke = '#d063d3'; stroke = '#5f19a2'; }else if(counties[i]['recordCount'] < 10 ){ fill = '#c358cd'; //stroke = '#7c29ae'; stroke = '#5f19a2'; }else if(counties[i]['recordCount'] < 28 ){ fill = '#993aba'; stroke = '#5f19a2'; stroke = '#5f19a2'; }else if(counties[i]['recordCount'] < 85 ){ fill = '#6d20a8'; stroke = '#330590'; //stroke = '#5f19a2'; }else{ fill = '#420b96'; stroke = '#25008a'; //stroke = '#5f19a2'; } //###Real messy way to create array of polygons. I need to find a much better solution counties[i].mapped = new gm.Polygon({ paths:countycoords, strokeColor: stroke, strokeOpacity: 0.9, strokeWeight: 1, fillColor: fill, fillOpacity: 0.7 }); } counties[i].mapped.setMap(map2); createInfobox2(counties[i].mapped, info); } //################################end county// for (var i=0; i<quads.length; i++) { //functionfrom QuadCoord.js var testarr = getQuadCoordinates(quads[i]['name']); //var info = "<b>"+counties[i]['fullName']+"</b><br/>"; info = "<b>"+testarr['common']+"</b><br/>Total Records: "+quads[i]['recordCount']+"<br/>Specimens: "+quads[i]['specimen']+"<br/>"+"Observations: "+quads[i]['observation']+"<br/>Publications: "+quads[i]['publication']; if(quads[i]['recordCount'] == 1){ fill = '#ffc7e9'; //stroke = '#DF7ad6'; stroke = '#330590'; }else if(quads[i]['recordCount'] < 4){ fill = '#e586d7'; //stroke = '#d063d3'; stroke = '#330590'; }else if(quads[i]['recordCount'] < 10 ){ fill = '#c358cd'; //stroke = '#7c29ae'; stroke = '#330590'; }else if(quads[i]['recordCount'] < 28 ){ fill = '#993aba'; //stroke = '#5f19a2'; stroke = '#330590'; }else if(quads[i]['recordCount'] < 85 ){ fill = '#6d20a8'; stroke = '#330590'; //stroke = '#5f19a2'; }else{ fill = '#420b96'; stroke = '#25008a'; //stroke = '#5f19a2'; } var coords = [ new gm.LatLng(testarr["lat1"], testarr["long2"]), new gm.LatLng(testarr["lat2"], testarr["long2"]), new gm.LatLng(testarr["lat2"], testarr["long1"]), new gm.LatLng(testarr["lat1"], testarr["long1"])]; //###Real messy way to create array of polygons. I need to find a much better solution quads[i].mapped = new gm.Polygon({ paths:coords, strokeColor: stroke, strokeOpacity: 0.9, strokeWeight: 1, fillColor: fill, fillOpacity: 0.7 }); var midlong = (parseFloat(testarr["long1"]) + .06); var midlat = (parseFloat(testarr["lat1"]) + .06); quads[i].mapped.latCenter = new gm.LatLng(midlat, midlong); //quads[i].mapped.content = quads[i]["info"]; quads[i].mapped.content = info; quads[i].mapped.setOptions({ zIndex: 2 }); quads[i].mapped.setMap(map); createInfobox(quads[i].mapped, quads[i].mapped.content, quads[i].mapped.latCenter); } outlinemapped = true; } function createInfobox(quad, content, position){ google.maps.event.addListener(quad, 'click', function() { infoWindow.setContent("<div style = 'font-size:90%'>"+content+"</div>"); infoWindow.setPosition(position); infoWindow.open(map); }); } //test function for placing infobox on clicked location instead of calculating midpoint function createInfobox2(quad, content){ google.maps.event.addListener(quad, 'click', function(e) { var latLng = e.latLng; infoWindow.setContent("<div style = 'font-size:90%;margin:0px;padding:0px'>"+content+"</div>"); infoWindow.setPosition(latLng); infoWindow.open(map2); }); } </script> </div> </body> </html>